当前位置: 首页 > 工具软件 > Optional > 使用案例 >

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

田晨
2023-12-01

首先准备一个测试实体:

@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 接口生成的异常
 类似资料: