Java8实战使用Optional解决空指针异常

首先准备一个测试实体:

@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 接口生成的异常

猜你喜欢

转载自blog.csdn.net/amosjob/article/details/127500720