开始
定义一个实体类User,实现get、set方法
public class User {String name;String sex;public User(String name, String sex) {this.name = name;this.sex = sex;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;} }
定义一个UserRepository,用户仓库,实现仓库里面对数据库的user表进行username字段查询,假设user表里面有了“张三”这条数据,当查询到张三的时候,我们就会返回一“张三”对象,没有“张三”这条数据,就会返回null
public class UserRepository {public User findUserByName(String name) {if (name.equals("张三")) {return new User("张三", "男");} else {return null;}} }
再main函数中进行引用,实例化UserRepository对象,调用里的findUserByName方法,然后打印性别,当我们查询的“张三”的是时候,我们是假设了user表里面有一条张三,那么就会返回这个张三的数据,此时打印出的性别是“男”。
public class Main {public static void main(String[] args) {UserRepository userRepository = new UserRepository();User user= userRepository.findUserByName("张三");System.out.println(user.getSex()); //男} }
这个时候我们去查询“李四”,就会出现报错;“NullPointerException”
因为表里面只有“张三”这条数据,没有李四,就会返回为null,然后,user.getSex()就会报错,都没有这个人,你还想知道他的性别。
public class Main {public static void main(String[] args) {UserRepository userRepository = new UserRepository();User user= userRepository.findUserByName("李四");System.out.println(user.getSex());} }
这个时候我们就需要加入if判断了,当有这个人,就是打印他的性别,
没有,就提示没有这个人。
if (user != null) {System.out.println(user.getSex());} else {System.out.println("没有这个人");}
此时我么就避免了"NullPointerException"空指针异常的问题,那我们联想下,用户进行查数据的时候,他根本不知道里面有没有他想要的数据。当数据量很大的时候,都要去使用if去判断吗,这样会显的代码非常臃肿,增加了代码的阅读性,难以维护,此时Optioanl解决了我们的问题。
Optional
可以看做一个容器,里面可以包含任何东西,也可以什么都不包含,
对UserRepository的findUserByName方法进行修改,
public Optional<User> findUserByName(String name) {if (name.equals("张三")) {return Optional.of(new User("张三", "男"));} else {return Optional.empty();}}
ifPresent和ifPresentOrElse
再main中进行修改,使用Optional容器来包含User,ifPresent方法,如果optionalUser里面含值就会执行user -> System.out.println(user.getSex()),没有就不会执行,就会报错。
public static void main(String[] args) {UserRepository userRepository = new UserRepository();Optional<User> optionalUser= userRepository.findUserByName("李四");optionalUser.ifPresent(user -> System.out.println(user.getSex()));}
如果值为空的时候,我们想执行一些其他的操作。就需要用到ifPresentOrElse方法,有值就会执行第一个参数,没有值就会执行第二个参数。
Optional<User> optionalUser= userRepository.findUserByName("李四");optionalUser.ifPresentOrElse(user -> System.out.println(user.getSex()),() -> System.out.println("没有这个人")); //没有这个人}
Optional的使用
Optional中的静态方法
of();
于创建一个包含指定值的Optional对象,使用of方法时必须要确定是有值的,
String txt = null; Optional<String> optionalString = Optional.of(txt); //就会抛出NullPointerException,
ofNullable();
创建一个包含指定值的Optional对象可以有值也可以是空的,这个时候就不会出现异常了。
String txt = null; Optional<String> optionalString = Optional.ofNullable(txt);
empty();
创建一个空的Optional对象。
Optional中的实例方法
orElseThrow()
不带参数
String txt = null;Optional<String> optionalString = Optional.ofNullable(txt);optionalString.orElseThrow(); //此时就会抛出一个异常:NoSuchElementException
带参数,自定义异常
String txt = null;Optional<String> optionalString = Optional.ofNullable(txt);optionalString.orElseThrow(() ->new RuntimeException("Optional is null")); // 抛出的异常为Optional is null
orElse()和orElseGet()方法
直接看代码,让你更好的理解
public static void main(String[] args) {String txt = "zhangsan";Optional<String> optionalString = Optional.ofNullable(txt);txt = optionalString.orElse(printf());System.out.println("txt的值是:" + txt);String txt1 = optionalString.orElseGet(() -> printf());System.out.println("txt1的值是:" + txt1);}public static String printf() {System.out.println("执行了printf方法");return "liSi";} //打印结果: //执行了printf方法 //txt的值是:zhangsan //txt1的值是:zhangsan
此时我们可以看到:
Optional有值时,orElse会执行,而orElseGet不会执行。
既然执行了orElse方法,并且我们返回的是“liSi”,为什么打印变量txt值时候又是打印的“zhangSan”,不是“liSi”我们可以看源码:
public T orElse(T other) {return value != null ? value : other;}
其实里面的注释也说的很清楚了:If a value is present, returns the value, otherwise returns other.
存在这个值,就返回这个值,不存在,就返回其他。
现在我看下没有值的情况下是怎么样的:
public static void main(String[] args) {String txt = null;Optional<String> optionalString = Optional.ofNullable(txt);txt = optionalString.orElse(printf());System.out.println("txt的值是:" + txt);String txt1 = optionalString.orElseGet(() -> printf());System.out.println("txt1的值是:" + txt1);}public static String printf() {System.out.println("执行了printf方法");return "liSi";} //打印结果: 执行了printf方法 txt的值是:liSi 执行了printf方法 txt1的值是:liSi
可以看到:
Optional值为null的时候,orElse会执行,orElseGet也会执行。
我们再看下orElseGet源码
public T orElseGet(Supplier<? extends T> supplier) {return value != null ? value : supplier.get();}
注释:If a value is present, returns the value, otherwise returns the result produced by the supplying function.
存在值,则返回该值,否则返回提供函数产生的结果。
总结
说白了就是传值就用orElse,需要调用方法获取就用orElseGet,
Optional有没有值的时候都会调用orElse,而orElseGet只有Optional没有值的时候才会被调用。