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());
}

