Java Optional类

创建Optional实例

Optional对象可能包含值也可能为空

    @Test
    public void test02(){
        Optional<User> u = Optional.empty();
        u.get();
    }

使用上面那种方法创建Optional实例,如果使用get()方法访问u变量的值会报 NoSuchElementException。

我们也可以使用ofNullable()和of()方法来创建包含值的Optional实例,我们在明确对象不为Null的时候可以使用of()方法,但是不确定对象存不存在的时候就使用ofNullable()方法。

    @Test
    public void test03(){
        User user = null;
        //使用of(),如果user为null的话会报空指针错误
        Optional<User> a = Optional.of(user);

        //使用ofNullable()方法,把null作为参数传入的时候不会报空指针异常
        Optional<User> b = Optional.ofNullable(user);
    }

访问Optional对象的值

从Optional实例中取回实践对象的方法之一是使用get()方法

    @Test
    public void testOptional04(){
        String name = "jin";
        Optional<String> user = Optional.ofNullable(name);
        assertEquals("jin", user.get());
    }

在第一个例子里面,如果调用get()方法的对象为null还是会报空指针异常,因此我们要首先判断调用get()方法的对象是否存在。我们可以调用isPresent()方法判断Optional实例是否存在,如果存在则返回true。

但是一个对象存在也并不能代表它下面的属性都村在,如果某个属性没有赋值的话该属性的值也可能为null,只不过对象调用get()方法获取该属性的时候不会报空指针异常。

    @Test
    public void testOptional05(){
        User user = new User(10,"jin");
        Optional<User> u = Optional.ofNullable(user);
        assertTrue(u.isPresent());
        assertEquals(u.get().getName(),user.getName());
    }

判断值是否存在还有另外一个方法ifPresent(),如果值存在则使用该值调用consumer,否则不做任何事情。

void ifPresent(Consumer<? super T> consumer)
如果值存在则使用该值调用 consumer , 否则不做任何事情。

opt.ifPresent( u -> assertEquals(user.getEmail(), u.getEmail()));

 上面的程序只有当用户不为空的时候才会去运行lamda表达式

返回默认值

Optional类提供了API用以返回对象值,或者对象为空的时候返回默认值,这里的第一个方法是orElse()方法,这个方法的工作方式就是如果有值则返回值,没有值则返回传递给它的参数值

    @Test
    public void testOptional06(){
        User user = new User(10,"jin");
        User user1 = null;
        //这里的user1为空所以返回了user对象,如果对象的初始值不为null的话orElse()方法里面的默认值就会被忽略
        User result = Optional.ofNullable(user1).orElse(user);
        assertEquals(result.getName(),"jin");
    }

这里的user1为空所以返回了user对象,如果对象的初始值不为null的话orElse()方法里面的默认值就会被忽略。

第二种同类型的API是orElseGet(),这个方法会在有值的时候返回值,如果没有值它就会执行作为参数传入的 Supplier(供应者) 函数式接口,并将返回其执行结果。

    @Test
    public void testOptional06(){
        User user = new User(10,"jin");
        User user1 = null;
        //这里的user1为空所以返回了user对象,如果对象的初始值不为null的话orElse()方法里面的默认值就会被忽略
        //User result = Optional.ofNullable(user1).orElse(user);
        User result = Optional.ofNullable(user1).orElseGet( () -> user);
        assertEquals(result.getName(),"jin");
    }

上面的代码里面,user1为空就执行了orElseGet()方法里面的方法并将结果返回来。

orElse() 和 orElseGet() 的不同之处

当对象为空的时候,两种方法都需要执行CreateUser()方法,看不出有什么区别。

    @Test
    public void testOptional07(){
        User user = new User(10,"jin");
        User user1 = null;
        //这里的user1为空所以返回了user对象,如果对象的初始值不为null的话orElse()方法里面的默认值就会被忽略
        System.out.println("****orElse方法*****");
        User result = Optional.ofNullable(user1).orElse(CreateUser());
        System.out.println("****orElseGet方法****");
        User result1 = Optional.ofNullable(user1).orElseGet(() -> CreateUser());
    }


    private User CreateUser(){
        System.out.println("****CreateUser****");
        return new User(10,"jin");
    }

执行结果:

****orElse方法*****
****CreateUser****
****orElseGet方法****
****CreateUser****

当对象不为空时,orElse()方法依然会执行CreateUser()方法而orElseGet()方法则不会再执行CreateUser()方法了。

    @Test
    public void testOptional07(){
        User user = new User(10,"jin");
        User user1 = null;
        //这里的user1为空所以返回了user对象,如果对象的初始值不为null的话orElse()方法里面的默认值就会被忽略
        System.out.println("****orElse方法*****");
        User result = Optional.ofNullable(user).orElse(CreateUser());
        System.out.println("****orElseGet方法****");
        User result1 = Optional.ofNullable(user).orElseGet(() -> CreateUser());
    }


    private User CreateUser(){
        System.out.println("****CreateUser****");
        return new User(10,"jin");
    }

执行结果如下:

****orElse方法*****
****CreateUser****
****orElseGet方法****

在执行较密集的调用时,比如调用 Web 服务或数据查询,这个差异会对性能产生重大影响

还有一个方法是orElseThrow()方法,它会在对象为null的时候抛我们自己指定的异常,而不总是抛空指针异常

    @Test
    public void testOptional08(){
        User user = new User(10,"jin");
        User user1 = null;
        User result1 = Optional.ofNullable(user1).orElseThrow(() -> new IllegalArgumentException());
    }

转换值:有很多种方法可以转换Optional的值,如map() filter()方法等,这两个方法的使用和Stream流中对应的方法很相似

    @Test
    public void testOptional09(){
        User user = new User(10,"jin");
        String name = Optional.ofNullable(user).map(u -> u.getName()).filter(a -> a.contains("h")).orElse("haha");
        System.out.println(name);
    }

与Stream API相结合,可以有巨大威力。

    @Test
    public void testOptional10(){
//        List<Employee> list = EmployeeData.getEmployees();
        List<Employee> list = null;
        Optional.ofNullable(list).orElse(Collections.emptyList())
                .stream()
                .map(e -> e.getAge())
                .filter(s -> s > 30)
                .forEach(System.out::println);
    }

理解、学习与使用 Java 中的 Optional - 张伯雨 - 博客园

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值