首先准备一个测试实体:
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class TestEntity {
private Optional<User> user;
private String testName;
private int age;
public Optional<User> getUser()
{
return user;
}
}
1、获取Optional的三种方式
public void demo1() {
TestEntity test = new TestEntity();
// 获取 Optional 对象
// 方式一,参数不能是null,是null抛异常
Optional<TestEntity> test1 = Optional.of(test);
// 方式二,参数可以是null
Optional<TestEntity> test2 = Optional.ofNullable(test);
// 方式三,获得一个空对象
Optional<TestEntity> test3 = Optional.empty();
}
2、Optional取值
public void demo2(){
TestEntity test = new TestEntity();
// 1、从对象中获取值
test.setTestName("zhangSan");
Optional<TestEntity> test4 = Optional.of(test);
Optional<String> optionalName = test4.map(TestEntity::getTestName);
boolean present = optionalName.isPresent();
if (present)
{
String name = optionalName.get();
System.out.println(name);
}
else
{
System.out.println("value is null");
}
// 2、使用 flatMap 取值
TestEntity testNew = new TestEntity();
testNew.setTestName("liSi");
Optional<TestEntity> test5 = Optional.of(testNew);
// 使用 flatMap 链接 Optional 对象,flatMap方法。使用流时,flatMap方法接受一个函数作为参数,这个函数的返回值是另一个流。
//这个方法会应用到流中的每一个元素,最终形成一个新的流的流。但是flagMap会用流的内容替
//换每个新生成的流。换句话说,由方法生成的各个流会被合并或者扁平化为一个单一的流。
String valueKnown = test5
.flatMap(TestEntity::getUser)
.map(User::getName)
// 设置默认值
.orElse("unknown");
System.out.println("test5 value: " + valueKnown);
// 组合取值
User user = new User();
TestEntity testEntity = new TestEntity();
Optional<User> userOptional = Optional.of(user);
Optional<TestEntity> testOptional = Optional.of(testEntity);
// 方式一
demo1(testOptional, userOptional);
// 方式二
Optional<Object> obj = testOptional.flatMap(tl -> userOptional.map(ul -> demo2(tl, ul)));
System.out.println(obj);
//过滤filter的使用
TestEntity filterEntity = new TestEntity();
Optional<TestEntity> test6 = Optional.of(filterEntity);
String valueFilter = test6
// 通过年龄过滤信息
.filter(tf -> tf.getAge() >= 20)
.flatMap(TestEntity::getUser)
.map(User::getName)
// 设置默认值
.orElse("unknown");
System.out.println("test6 value: " + valueFilter);
// 数据类型转换
// 与 Stream对象一样,Optional也提供了类似的基础类
// 型——OptionalInt、OptionalLong以及OptionalDouble——所以下列方法可
// 以不返回Optional<Integer>,而是直接返回一个OptionalInt类型的对象
Optional<Integer> number = stringToInt("number");
System.out.println(number);
// OptionalInt类型
List<Integer> list = Arrays.asList(1,3,5);
OptionalInt max = list.stream().mapToInt(value -> value * 2).max();
int asInt = max.getAsInt();
System.out.println(asInt);
// 也可以
int asInt1 = list.stream().mapToInt(value -> value * 2).min().getAsInt();
System.out.println(asInt1);
}
// 方式一
public void demo1(Optional<TestEntity> test, Optional<User> user) {
if (test.isPresent() && user.isPresent())
{
System.out.println(test.get());
System.out.println(user.get());
}
else
{
System.out.println("value is null");
}
}
// 方式二
public Object demo2(TestEntity tl, User ul) {
return "demo2";
}
// 将String转换为Integer,并返回一个Optional对象
public static Optional<Integer> stringToInt(String s) {
try {
return Optional.of(Integer.parseInt(s));
} catch (NumberFormatException e) {
return Optional.empty();
}
}
3、Optional的API详解
序号 | 方法 | 描述 |
1 | empty | 返回一个空的 Optional 实例 |
2 | filter | 如果值存在并且满足提供的谓词,就返回包含该值的 Optional 对象;否则返回一个空的 Optional 对象 |
3 | flatMap | 如果值存在,就对该值执行提供的 mapping 函数调用,返回一个 Optional 类型的值,否则就返回一个空的 Optional 对象 |
4 | get | 如果该值存在,将该值用 Optional 封装返回,否则抛出一个 NoSuchElementException 异常 |
5 | ifPresent | 如果值存在,就执行使用该值的方法调用,否则什么也不做 |
6 | isPresent | 如果值存在就返回 true,否则返回 false |
7 | map | 如果值存在,就对该值执行提供的 mapping 函数调用 |
8 | of | 将指定值用 Optional 封装之后返回,如果该值为 null,则抛出一个 NullPointerException 异常 |
9 | ofNullable | 将指定值用 Optional 封装之后返回,如果该值为 null,则返回一个空的 Optional 对象 |
10 | orElse | 如果有值则将其返回,否则返回一个默认值 |
11 | orElseGet | 如果有值则将其返回,否则返回一个由指定的 Supplier 接口生成的值 |
12 | orElseThrow | orElseThrow 如果有值则将其返回,否则抛出一个由指定的 Supplier 接口生成的异常 |