Java - JDK8 新特性 Optional 使用

简介: Java - JDK8 新特性 Optional 使用


空指针异常是导致Java应用程序失败的最常见原因。以前,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。受到Google Guava的启发,Optional类已经成为Java 8类库的一部分。Optional实际上是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。

  • Optional.of()或者Optional.ofNullable():创建Optional对象,差别在于of不允许参数是null,而ofNullable则无限制
// 参数不能是nullOptional<Integer>optional1=Optional.of(1);
// 参数可以是nullOptional<Integer>optional2=Optional.ofNullable(null);
// 参数可以是非nullOptional<Integer>optional3=Optional.ofNullable(2);
  • Optional.empty():所有null包装成的Optional对象
Optional<Integer>optional1=Optional.ofNullable(null);
Optional<Integer>optional2=Optional.ofNullable(null);
System.out.println(optional1==optional2); // trueSystem.out.println(optional1==Optional.<Integer>empty()); // trueObjecto1=Optional.<Integer>empty();
Objecto2=Optional.<String>empty();
System.out.println(o1==o2); // true
  • isPresent():判断值是否存在
Optional<Integer>optional1=Optional.ofNullable(1);
Optional<Integer>optional2=Optional.ofNullable(null);
// isPresent判断值是否存在System.out.println(optional1.isPresent() ==true);
System.out.println(optional2.isPresent() ==false);
  • ifPresent(Consumer consumer):如果option对象保存的值不是null,则调用consumer对象,否则不调用
Optional<Integer>optional1=Optional.ofNullable(1);
Optional<Integer>optional2=Optional.ofNullable(null);
// 如果不是null, 调用Consumeroptional1.ifPresent(newConsumer<Integer>() {
@Overridepublicvoidaccept(Integert) {
System.out.println("value is "+t);
    }
});
// null, 不调用Consumeroptional2.ifPresent(newConsumer<Integer>() {
@Overridepublicvoidaccept(Integert) {
System.out.println("value is "+t);
    }
});
  • orElse(value):如果optional对象保存的值不是null,则返回原来的值,否则返回value
Optional<Integer>optional1=Optional.ofNullable(1);
Optional<Integer>optional2=Optional.ofNullable(null);
// orElseSystem.out.println(optional1.orElse(1000) ==1); // trueSystem.out.println(optional2.orElse(1000) ==1000); // true
  • orElseGet(Supplier supplier):功能与orElse一样,只不过orElseGet参数是一个对象
Optional<Integer>optional1=Optional.ofNullable(1);
Optional<Integer>optional2=Optional.ofNullable(null);
System.out.println(optional1.orElseGet(() -> {
return1000;
}) ==1); // trueSystem.out.println(optional2.orElseGet(() -> {
return1000;
}) ==1000); // true
  • orElseThrow():值不存在则抛出异常,存在则什么不做,有点类似Guava的Precoditions
Optional<Integer>optional1=Optional.ofNullable(1);
Optional<Integer>optional2=Optional.ofNullable(null);
optional1.orElseThrow(()->{thrownewIllegalStateException();});
try {
// 抛出异常optional2.orElseThrow(()->{thrownewIllegalStateException();});
} catch(IllegalStateExceptione) {
e.printStackTrace();
}
  • filter(Predicate):判断Optional对象中保存的值是否满足Predicate,并返回新的Optional
Optional<Integer>optional1=Optional.ofNullable(1);
Optional<Integer>optional2=Optional.ofNullable(null);
Optional<Integer>filter1=optional1.filter((a) ->a==null);
Optional<Integer>filter2=optional1.filter((a) ->a==1);
Optional<Integer>filter3=optional2.filter((a) ->a==null);
System.out.println(filter1.isPresent()); // falseSystem.out.println(filter2.isPresent()); // trueSystem.out.println(filter2.get().intValue() ==1); // trueSystem.out.println(filter3.isPresent()); // false
  • map(Function):对Optional中保存的值进行函数运算,并返回新的Optional(可以是任何类型)
Optional<Integer>optional1=Optional.ofNullable(1);
Optional<Integer>optional2=Optional.ofNullable(null);
Optional<String>str1Optional=optional1.map((a) ->"key"+a);
Optional<String>str2Optional=optional2.map((a) ->"key"+a);
System.out.println(str1Optional.get()); // key1System.out.println(str2Optional.isPresent()); // false
  • flatMap():功能与map()相似,差别请看如下代码。flatMap方法与map方法类似,区别在于mapping函数的返回值不同。map方法的mapping函数返回值可以是任何类型T,而flatMap方法的mapping函数必须是Optional
Optional<Integer>optional1=Optional.ofNullable(1);
Optional<Optional<String>>str1Optional=optional1.map((a) -> {
returnOptional.<String>of("key"+a);
});
Optional<String>str2Optional=optional1.flatMap((a) -> {
returnOptional.<String>of("key"+a);
});
System.out.println(str1Optional.get().get()); // key1System.out.println(str2Optional.get()); // key1
目录
相关文章
|
16天前
|
存储 Java 开发者
什么是java的Compact Strings特性,什么情况下使用
Java 9引入了紧凑字符串特性,优化了字符串的内存使用。它通过将字符串从UTF-16字符数组改为字节数组存储,根据内容选择更节省内存的编码方式,通常能节省10%至15%的内存。
|
22天前
|
容器
jdk8新特性-详情查看文档
jdk8新特性-详情查看文档
39 7
|
25天前
|
存储 Java 数据挖掘
Java 8 新特性之 Stream API:函数式编程风格的数据处理范式
Java 8 引入的 Stream API 提供了一种新的数据处理方式,支持函数式编程风格,能够高效、简洁地处理集合数据,实现过滤、映射、聚合等操作。
41 6
|
28天前
|
Oracle 安全 Java
深入理解Java生态:JDK与JVM的区分与协作
Java作为一种广泛使用的编程语言,其生态中有两个核心组件:JDK(Java Development Kit)和JVM(Java Virtual Machine)。本文将深入探讨这两个组件的区别、联系以及它们在Java开发和运行中的作用。
70 1
|
1月前
|
IDE Java 编译器
开发 Java 程序一定要安装 JDK 吗
开发Java程序通常需要安装JDK(Java Development Kit),因为它包含了编译、运行和调试Java程序所需的各种工具和环境。不过,某些集成开发环境(IDE)可能内置了JDK,或可使用在线Java编辑器,无需单独安装。
72 1
|
1月前
|
分布式计算 Java API
Java 8引入了流处理和函数式编程两大新特性
Java 8引入了流处理和函数式编程两大新特性。流处理提供了一种声明式的数据处理方式,使代码更简洁易读;函数式编程通过Lambda表达式和函数式接口,简化了代码书写,提高了灵活性。此外,Java 8还引入了Optional类、新的日期时间API等,进一步增强了编程能力。这些新特性使开发者能够编写更高效、更清晰的代码。
35 4
|
2月前
|
存储 Java API
优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。
【10月更文挑战第19天】本文介绍了如何优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。内容包括Map的初始化、使用Stream API处理Map、利用merge方法、使用ComputeIfAbsent和ComputeIfPresent,以及Map的默认方法。这些技巧不仅提高了代码的可读性和维护性,还提升了开发效率。
100 3
|
2月前
|
设计模式 Java API
[Java]静态代理与动态代理(基于JDK1.8)
本文介绍了代理模式及其分类,包括静态代理和动态代理。静态代理分为面向接口和面向继承两种形式,分别通过手动创建代理类实现;动态代理则利用反射技术,在运行时动态创建代理对象,分为JDK动态代理和Cglib动态代理。文中通过具体代码示例详细讲解了各种代理模式的实现方式和应用场景。
38 0
[Java]静态代理与动态代理(基于JDK1.8)
|
Java 测试技术
Java特性组合的通用方案
Java特性组合的通用方案
198 0
|
1天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者