引言:学习一门新技术,我们一定要带着疑问去学。不仅要搞清楚这门技术的由来和使用方法,更要搞清楚学了这门技术对我们敲代码有什么好处。
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. 总结
-
- 遇到可能会发生空指针的时候,可以将结果放到 Optional.ofNullable() 里面,然后使用 orElse() 设置默认值。
-
- 学会与 lambda 表达式连用。
近期评论