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详解

序号方法描述
1empty返回一个空的 Optional 实例
2filter如果值存在并且满足提供的谓词,就返回包含该值的 Optional 对象;否则返回一个空的 Optional 对象
3flatMap如果值存在,就对该值执行提供的 mapping 函数调用,返回一个 Optional 类型的值,否则就返回一个空的 Optional 对象
4get如果该值存在,将该值用 Optional 封装返回,否则抛出一个 NoSuchElementException 异常
5ifPresent如果值存在,就执行使用该值的方法调用,否则什么也不做
6isPresent如果值存在就返回 true,否则返回 false
7map如果值存在,就对该值执行提供的 mapping 函数调用
8of

将指定值用 Optional 封装之后返回,如果该值为 null,则抛出一个 NullPointerException 异常

9ofNullable将指定值用 Optional 封装之后返回,如果该值为 null,则返回一个空的 Optional 对象
10orElse如果有值则将其返回,否则返回一个默认值
11orElseGet如果有值则将其返回,否则返回一个由指定的 Supplier 接口生成的值
12orElseThroworElseThrow 如果有值则将其返回,否则抛出一个由指定的 Supplier 接口生成的异常
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值