Java 8可选(Optional)

时间:2020-02-23 14:34:53  来源:igfitidea点击:

在本教程中,我们将看到Java 8可选。
你有没有把nullpointerexcept视为java开发人员?
如果我们有经验丰富的Java Developer,则在某个时间点可能有nullpointerexception。

我们可能会同意NullPointerException是新手或者专家核心Java开发人员的痛苦。

如果我们想要避免NullPointerException,我们必须在很多防御码。
让我们在一个例子的帮助下看看。

package org.igi.theitroad;
 
public class Employee {
	private String name;
	private int age;
	
	public Employee(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

创建一个名为"javafindemployeamain.java"的主类

package org.igi.theitroad;
 
import java.util.ArrayList;
import java.util.List;
 
public class JavaFindEmployeeMain {
	
	public static void main(String[] args)
	{
		List<Employee> employeeList = createEmployeeList();
		Employee employee = findEmployee(employeeList,"Adam");
		System.out.println("Employee name: "+employee.getName());
	}
	
	public static Employee findEmployee(List<Employee> employeeList,String name)
	{
		for(Employee e:employeeList)
		{
			if(e.getName().equalsIgnoreCase(name))
			{
				return e;
			}
		}
		return null;
	}
	public static List<Employee> createEmployeeList()
	{
		List<Employee> employeeList=new ArrayList<>();
		
		Employee e1=new Employee("John",21);
		Employee e2=new Employee("Martin",22);
		Employee e3=new Employee("Mary",31);
		Employee e4=new Employee("Stephan",18);
		Employee e5=new Employee("Gary",26);
		
		employeeList.add(e1);
		employeeList.add(e2);
		employeeList.add(e3);
		employeeList.add(e4);
		employeeList.add(e5);
		
		return employeeList;
		
	}
}

运行上面的程序时,我们将得到以下输出:

Exception in thread “main" java.lang.NullPointerException
at org.igi.theitroad.JavaOptionalMain.main(JavaOptionalMain.java:12)

正如我们所看到的,"亚当"不存在于员工的家中,这就是为什么我们在此处获得NullPointerException。

你在这里看到这个问题吗?
当我们尝试在列表中找到员工时,我们忘了检查null。
当我们调用库函数时,这通常会发生这种情况,并且它返回NULL并且我们忘记检查。

Java 8可选

我们可以使用可选来解决此问题。
我们可以如下更改"JavaOptionMain"。

package org.igi.theitroad;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
 
public class JavaOptionalMain {
	
	public static void main(String[] args)
	{
		List<Employee> employeeList = createEmployeeList();
		Optional<Employee> employeeOpt = findEmployee(employeeList,"Adam");
		if(employeeOpt.isPresent())
		{
			Employee employee = employeeOpt.get();
			System.out.println("Employee name: "+employee.getName());
		}
		else
		{
			System.out.println("There is no employee with name Adam");
		}
	}
	
	public static Optional<Employee> findEmployee(List<Employee> employeeList,String name)
	{
		for(Employee e:employeeList)
		{
			if(e.getName().equalsIgnoreCase(name))
			{
				return Optional.of(e);
			}
		}
		return Optional.empty();
	}
	public static List<Employee> createEmployeeList()
	{
		List<Employee> employeeList=new ArrayList<>();
		
		Employee e1=new Employee("John",21);
		Employee e2=new Employee("Martin",22);
		Employee e3=new Employee("Mary",31);
		Employee e4=new Employee("Stephan",18);
		Employee e5=new Employee("Gary",26);
		
		employeeList.add(e1);
		employeeList.add(e2);
		employeeList.add(e3);
		employeeList.add(e4);
		employeeList.add(e5);
		
		return employeeList;
	}
}

我们可能认为我们也可以在JavaFindemployeBAIN中处理NULL,但是当从方法返回可选时,它意味着可以从方法中预期缺失值。

创建可选的方法

有多种方法可以创建可选。

空可选

我们可以使用静态工厂方法"空"创建空可选对象

Optional<Employee> optCar = Optional.empty();

从非空值中可选

我们可以使用静态工厂方法"of"从非空值创建可选的

Optional<Employee> optCar = Optional.of(employee);

如果员工为null,则上述方法将抛出nullpointerexception。

从null或者非null值可选

我们可以使用静态出厂方法"OFNULLABLE"从NULL或者非空值创建可选

Optional<Employee> optCar = Optional.ofNullable(employee);

从可选中获取值

我们可以使用get()方法从可选中检索值,但它是最不安的。
如果未存在值,则它将抛出nosuchelementException,因此我们需要在调用get()方法之前确保我们调用IsPresent()方法。

在可选中检查值

我们可以检查是否有值在可选的ispresent方法中挂红。

public static void main(String[] args)
	{
	        List<Employee> employeeList = createEmployeeList();
		Optional<Employee> employeeOpt = findEmployee(employeeList,"Adam");
		if(employeeOpt.isPresent())
		{
			Employee employee = employeeOpt.get();
			System.out.println("Employee name: "+employee.getName());
		}
		else
		{
			System.out.println("There is no employee with name Adam");
		}
	}

可选的条件行动

如果在可选中存在值,则可以使用ifpresent方法执行操作。
如下更改JavaOptionMain中的主要方法

public static void main(String[] args)
	{
		List<Employee> employeeList = createEmployeeList();
		Optional<Employee> employeeOpt1 = findEmployee(employeeList,"Adam");
		Optional<Employee> employeeOpt2 = findEmployee(employeeList,"John");
		
		employeeOpt1.ifPresent((employee)->System.out.println("Employee name: "+employee.getName()+" found in list"));
		employeeOpt2.ifPresent((employee)->System.out.println("Employee name: "+employee.getName()+" found in list"));
 
	}

运行此程序时,我们将得到以下输出:

Employee name: Dummy
Employee name: John found in list

如我们所见,如果列表中存在的员工姓名,那么只有我们正在打印员工姓名才能执行任何操作。

使用orelse可选的默认值

我们可以返回默认值,以防使用orelse方法在可选中没有值。
如下更改JavaOptionMain中的主要方法

public static void main(String[] args)
	{
		List<Employee> employeeList = createEmployeeList();
		Optional<Employee> employeeOpt = findEmployee(employeeList,"Adam");
		Employee employee1 = employeeOpt.orElse(new Employee("Dummy",0));
		System.out.println("Employee name: "+employee1.getName());
		
		Optional<Employee> employeeOpt2 = findEmployee(employeeList,"Martin");
		Employee employee2= employeeOpt2.orElse(new Employee("Dummy",0));
		System.out.println("Employee name: "+employee2.getName());
		
	}

请注意,即使在可选中存在值,默认对象也将克隆。

使用orelseget可选的默认值

Orelseget是Orelse的懒人柜台部分。
它将供应商担任参数,只有在可选中不存在值时,才会调用。

如下更改JavaOptionMain中的主要方法

public static void main(String[] args)
	{
		List<Employee> employeeList = createEmployeeList();
		Optional<Employee> employeeOpt = findEmployee(employeeList,"Adam");
		Employee employee1 = employeeOpt.orElseGet(()->new Employee("Dummy",0));
		System.out.println("Employee name: "+employee1.getName());
		
		Optional<Employee> employeeOpt2 = findEmployee(employeeList,"Martin");
		Employee employee2 = employeeOpt2.orElseGet(()->new Employee("Dummy",0));
		System.out.println("Employee name: "+employee2.getName());
		
	}

从可选中抛出异常

如果可选为空,则可以使用Orelsethrow抛出异常。
它类似于get()方法,但在这种情况下,我们可以选择抛出任何异常rathar,而不是nosuchmethodexception。
如下更改JavaOptionMain中的主要方法

public static void main(String[] args)
	{
		List<Employee> employeeList = createEmployeeList();
		Optional<Employee> employeeOpt = findEmployee(employeeList,"Adam");
		Employee employee1 = employeeOpt.orElseThrow(() -> new RuntimeException("Employee not found"));
		System.out.println("Employee name: "+employee1.getName());
		
		Optional<Employee> employeeOpt2 = findEmployee(employeeList,"Martin");
		Employee employee2 = employeeOpt2.orElseThrow(() -> new RuntimeException("Employee not found"));
		System.out.println("Employee name: "+employee2.getName());
		
	}