Java 8可选(Optional)
在本教程中,我们将看到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()); }