有了Optional,代码竟然如此优雅!

·  阅读 3463
有了Optional,代码竟然如此优雅!

引言:学习一门新技术,我们一定要带着疑问去学。不仅要搞清楚这门技术的由来和使用方法,更要搞清楚学了这门技术对我们敲代码有什么好处。

1. 为什么要使用 Optional?

1.1 场景一

小明在公司写代码的时候遇到一个问题:获取一个学生所在班级的教室的编号,小明灵机一动嗖嗖嗖就敲出来了:

String  code =  user.getMyClass().getClassroom().getCode();
复制代码

“可是这其中任何对象为空的时候肯就会抛出空指针异常啊!”想到这里,小明立马做出了修改:

if (null != user) {
      MyClass myClass = user.getMyClass();
      if (null != myClass) {
          Classroom classroom = myClass.getClassroom();
          if (null != classroom) {
              String code = classroom.getCode();
          }
      }
  }
复制代码

小明看着自以为很优雅的代码笑了起来:“我可真是个大聪明!嘿嘿嘿!”

“不过,这代码怎么看起来像套娃似的?有什么解决办法吗?“小明顿时陷入了沉默中。。。。。。

1.2 场景二

小明的同事小王上周末自学了 Lambda,想着能够秀一把,好好展现一下自己真正的实力。

他遇到一个问题:获取年龄大于21岁的学生中的最大年龄。

他思索片刻,写下如下代码:

int maxAge = userList.stream().map(user -> user.getAge()).filter(age -> age > 21).mapToInt(Integer::intValue).max().getAsInt();
复制代码

可是一运行报错了:

小王一想,肯定遇到空指针了,那我改动一下:

Stream<Integer> integerStream = userList.stream().map(user -> user.getAge()).filter(age -> age > 21);
if(null != integerStream){
    int maxAge = integerStream.mapToInt(Integer::intValue).max().getAsInt();
    System.out.println(maxAge);
}
复制代码

再运行:

小王傻眼了。。。。。。

1.3 认识 optional

小明和小王之所以傻眼,是因为他们没有灵活使用 optional。

optional 是 Java 8 引入的一个新特性,它就像一个容器,可以包含对象,也可以为空,从而避免空指针。

2. Optional 常用方法

2.1 of( )

将一个特定值放在 optional 容器里面,并返回一个 optional 对象。但是这个特定值不能为 null ,否则会抛出 NullPointerException 异常。

举例:

Optional<Integer> number1 = Optional.of(123);
System.out.println(number1);
System.out.println("----------------");
Optional<Integer> number2 = Optional.of(null);
System.out.println(number2);
复制代码

运行结果:

2.2 ofNullable( )

将一个特定值放在 optional 容器里面,并返回一个 optional 对象,这个特定值可以为 null 。如果放入的值为 null ,则返回一个空的 optional 对象。

举例:

Optional<String> number1 = Optional.ofNullable("祝福祖国72周年生日快乐");
System.out.println(number1);
System.out.println("----------------");
Optional<Integer> number2 = Optional.ofNullable(null);
System.out.println(number2);
复制代码

运行结果:

2.3 isPresent( )

如果返回的对象没有值,调用 isPresent() 方法会返回 false ,否则返回 true 。

举例:

List<User> userList = Stream.of(new User("张三", 18), new User("李四", 21)).collect(Collectors.toList());
boolean present = userList.stream().filter(user -> user.getAge() > 21).findFirst().isPresent();
System.out.println(present);
复制代码

运行结果:

2.4 get( )

调用这个方法有值就返回,没值就报错。

举例:

List<User> userList = Stream.of(new User("张三", 18), new User("李四", 21)).collect(Collectors.toList());
User user1 = userList.stream().filter(user -> user.getAge() > 18).findFirst().get();
System.out.println(user1);
System.out.println("----------");
User user2 = userList.stream().filter(user -> user.getAge() > 21).findFirst().get();
System.out.println(user2);
复制代码

运行结果:

2.5 ifPresent( )

有值就调用这个方法,否则不调用

举例:

List<User> userList = Stream.of(new User("张三", 18), new User("李四", 21)).collect(Collectors.toList());
userList.stream().filter(user -> user.getAge() > 18).findFirst().ifPresent(user -> {
    System.out.println(user);
});
System.out.println("----------");
userList.stream().filter(user -> user.getAge() > 21).findFirst().ifPresent(user -> {
    System.out.println(11111111);
    System.out.println(user);
});
复制代码

运行结果:

2.6 orElse( )

有值就返回,否则返回一个给定的默认值。

举例:

List<Integer> nums = Stream.of(11, 17, 34, 78).collect(Collectors.toList());
Integer num1 = nums.stream().filter(w -> w > 11).mapToInt(Integer::intValue).max().orElse(99);
System.out.println(num1);
System.out.println("--------");
Integer num2 = nums.stream().filter(w -> w > 78).findFirst().orElse(99);
System.out.println(num2);
复制代码

运行结果:

2.7 orElseGet( )

有值就返回,否则通过一个方法返回一个给定的默认值。

举例:

public static int getNum(){
    return 12;
}
public static void main(String[] args) {
  List<Integer> nums = Stream.of(11, 17, 34, 78).collect(Collectors.toList());
  Integer num1 = nums.stream().filter(w -> w > 11).mapToInt(Integer::intValue).max().orElse(99);
  System.out.println(num1);
  System.out.println("--------");
  Integer num2 = nums.stream().filter(w -> w > 78).findFirst().orElseGet(()->2);
  System.out.println(num2);
  Integer num3 = nums.stream().filter(w -> w > 78).findFirst().orElseGet(()->getNum());
  System.out.println("--------");
  System.out.println(num3);
}
复制代码

运行结果:

3. Optional 小案例

User user1= null;
String code1 = Optional.ofNullable(user1).map(w -> w.getMyClass().getClassroom().getCode()).orElse("没有找到符合要求的编码");
System.out.println(code1);
System.out.println("---------");
User user2 = new User("赵敏", 19, new MyClass(new Classroom("13")));
String code2 = Optional.ofNullable(user2).map(w -> w.getMyClass().getClassroom().getCode()).orElse("没有找到符合要求的编码");
System.out.println(code2);
复制代码

运行结果:

4. 总结

    1. 遇到可能会发生空指针的时候,可以将结果放到 Optional.ofNullable() 里面,然后使用 orElse() 设置默认值。
    1. 学会与 lambda 表达式连用。
分类:
后端
分类:
后端
收藏成功!
已添加到「」, 点击更改