Java8的新特性--Optional


Optional

一、Optional类是什么?

Optional 类(java.util.Optional)是一个容器类,代表一个值存在或不存在,原来用null表示一个值不存在,现在用Optional可以更好的表达这个概念。并且可以避免空指针。

二、Optional类常用的方法

1. 创建Optional实例

这个类型的对象可能包含值,也可能为空。

1.1 Optional.of(T)

创建一个Optional实例

    @Test
    public void test01(){
        创建一个带泛型的Optional容器类
        Optional<Employee> employee = Optional.of(new Employee());
        System.out.println(employee.get());

        //会报空指针异常
        Optional<Employee> employee1 = Optional.of(null);
        System.out.println(employee1.get());

    }
}

这里我们需要注意,Optional.of(null),of方法传null时,会报NullPointException.

1.2 Optional.empty()

创建一个空的Optional实例

    @Test
    public void test02(){
        //构建了一个空的Optional实例,里面没有任何东西
        Optional<Employee> employee = Optional.empty();
        System.out.println(employee.get());//输出 java.util.NoSuchElementException: No value present
    }
1.3. Optional.ofNullable(T t)

Optional类中的of()方法不允许包装null,但是ofNullable()方法可以,传递到该方法中的若为null,则构建一个空的Optional实例

    @Test
    public void test03(){
        //不会报空指针异常
        //Optional类中的of()方法不允许包装null,但是ofNullable()方法可以,传递到该方法中的若为null,则构建一个空的Optional实例
        Optional<Employee> employee2 = Optional.ofNullable(null);
        if(employee2.isPresent()){
            System.out.println(employee2.get());
        }else{
            System.out.println("------------");
        }
    }

我们来看一下ofNullable源码

    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

即如果传进来的是null则直接调用了empty(),不为null时才调用of(value)。

1.4. 小结

这个类型的对象可能包含值,也可能为空。我们可以使用Optional.empty()方法创建一个空的Optional,也可以使用of() 和 ofNullable() 方法创建包含值的 Optional。这俩方法的不同之处在于如果把null值作为参数传递进去,of()方法会抛出NullPointerException。所以,我们应该在对象不为 null的时候使用 of(),对象即可能是 null 也可能是非null,使用 ofNullable() 方法。

2.访问Optional对象的值

2.1 get()获取值
    @Test
    public void test01(){
        创建一个带泛型的Optional容器类
        Optional<Employee> employee = Optional.of(new Employee());
        //获取值
        System.out.println(employee.get());
    }

从 Optional 实例中取回实际值对象的方法之一是使用 get() 方法。不过,这个方法会在值为null的时候抛出异常,为了避免我们要先验证是否有值。

2.2 isPresent()验证是否有值
    @Test
    public void test03(){
        //不会报空指针异常
        //Optional类中的of()方法不允许包装null,但是ofNullable()方法可以,传递到该方法中的若为null,则构建一个空的Optional实例
        Optional<Employee> employee2 = Optional.ofNullable(null);
        //判断是否存在
        if(employee2.isPresent()){//存在
            System.out.println(employee2.get());
        }else{//不存在
            System.out.println("------------");
        }
    }
2.3 ifPresent()

检查是否有值的时候还可以用ifPresent(),该方法除了执行检查,还可以接受一个Consumer(消费者)参数,如果对象不是空的,就执行传入的Lambda表达式。

    @Test
    public void test04(){
        Optional<Employee> employee2 = Optional.ofNullable(new Employee());
        //如果对象不是空的,就执行传入的Lambda表达式。
        employee2.ifPresent(e -> System.out.println(e.getAge()));
    }

3. 返回默认值

Optional类提供API用以返回对象值,或者在对象为空的时候返回默认值。

3.1 orElse(T t)

如果调用对象包含有值,那么返回该值,否则返回orElse()方法中的对象。

    @Test
    public void test05(){
        Optional<Employee> op = Optional.ofNullable(new Employee());
        Employee em = op.orElse(new Employee("默认姓名", 20, 1000));
        System.out.println(em);//打印Employee{name='null', age=0, salary=0.0}

        Optional<Employee> op1 = Optional.ofNullable(null);
        Employee em1 = op1.orElse(new Employee("默认姓名", 20, 1000));
        System.out.println(em1);//打印Employee{name='默认姓名', age=20, salary=1000.0}
    }
3.2 orElseGet(Supplier s)
    @Test
    public void test06(){
        Optional<Employee> op = Optional.ofNullable(new Employee());
        Employee em = op.orElseGet(() -> new Employee("默认姓名", 20, 1000));
        System.out.println(em);//打印Employee{name='null', age=0, salary=0.0}

        Optional<Employee> op1 = Optional.ofNullable(null);
        Employee em1 = op1.orElseGet(() -> new Employee("默认姓名", 20, 1000));
        System.out.println(em1);//打印Employee{name='默认姓名', age=20, salary=1000.0}
    }
3.3 orElse(T t)和orElseGet(Supplier s)的不同

先来看看传入对象都为null时


    public Employee createNewEmployee(){
        System.out.println("==========创建一个新对象====");
        return new Employee("默认姓名1", 20, 1000);
    }
    
    @Test
    public void test07(){

        //传入对象都为null时
        Employee e = null;
        Optional<Employee> op = Optional.ofNullable(e);
        System.out.println("-----orElse----");
        Employee em = op.orElse(createNewEmployee());
        System.out.println("-----orElseGet----");
        Employee em1 = op.orElseGet(() -> createNewEmployee());
    }

运行结果:两种方法都调用了 createNewEmployee() 方法


-----orElse----
==========创建一个新对象====
-----orElseGet----
==========创建一个新对象====
    //不同之处
    @Test
    public void test08(){
        //传入对象都不为null时
        Employee e = new Employee("默认姓名", 20, 1000);
        Optional<Employee> op = Optional.ofNullable(e);
        System.out.println("-----orElse----");
        Employee em = op.orElse(createNewEmployee());
        System.out.println("-----orElseGet----");
        Employee em1 = op.orElseGet(() -> createNewEmployee());
    }

运行结果,只有一个方法调用了createNewEmployee()

-----orElse----
==========创建一个新对象====
-----orElseGet----

这个例子说明,两个 Optional 对象都包含非空值,两个方法都会返回对应的非空值。不过,orElse() 方法仍然创建了 User 对象。与之相反,orElseGet() 方法不创建 User 对象。

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

4. 转换值

4.1 map(Function f)

若有值则对其处理,并返回处理后的Optional,否则返回Optional.empty()。

    @Test
    public void test09(){

        String str = Optional.ofNullable(new Employee())
                .map(Employee::getName).orElse("张三");
        System.out.println(str);//打印输出张三
        Employee e = new Employee("默认姓名", 20, 1000);
        String str2 = Optional.ofNullable(e)
                .map(Employee::getName).orElse("张三");
        System.out.println(str2);//打印输出默认姓名

    }
4.2 flatMap(Function mapper)

与map类似,但要求返回值必须是Optional。

    @Test
    public void test10(){
        Employee em = new Employee("默认姓名", 20, 1000);

        //map
        Optional<String> s1 = Optional.ofNullable(em)
                .map(Employee::getName);
        System.out.println(s1);
        //flatMap  要求返回的是Optional  避免空指针
        Optional<String> s2 = Optional.ofNullable(em)
                .flatMap(e -> Optional.of(e.getName()));
        System.out.println(s2);

    }

5. 过滤值

除了转换值之外,Optional 类也提供了按条件“过滤”值的方法。

5.1 filter()

filter() 接收一个Predicate参数,返回测试结果为true的值,如果测试结果为false,会返回一个空的Optional。

    @Test
    public void test11(){

        //map
        Optional<Employee> employee = Optional.ofNullable(new Employee())
                .filter(e -> e.getName() != null);
        System.out.println(employee);//返回一个空的Optional  Optional.empty
        Employee em = new Employee("默认姓名", 20, 1000);

        Optional<Employee> employee1 = Optional.ofNullable(em)
                .filter(e -> e.getName() != null);
        System.out.println(employee1);//Optional[Employee{name='默认姓名', age=20, salary=1000.0}]

    }

如果通过过滤器测试,result 对象会包含非空值。

三、总结

Optional类其实就是一个封装了一个元素的容器,而这个元素可以是null也可以是其它任意类型的。Optional是Java语言的有益补充,它旨在减少代码中的NullPointerExceptions,虽然不能完全消除这些异常,他也是精心设计,自然融入了Java8函数式支持的功能

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java8中的Optional类是一个容器对象,可以包含null或非null值。它提供了一种优雅的方式来处理null值,避免了NullPointerException异常的出现。Optional类可以用于返回值、方法参数和实例变量等场景中,使代码更加简洁、清晰和安全。使用Optional类可以使代码更加健壮,减少了代码中的null检查和异常处理,提高了代码的可读性和可维护性。 ### 回答2: Optional类是Java 8中新引入的一个类,它的主要作用是在避免NullPointerException的情况下将null值返回给调用者。这个类是一个容器对象,它可以保存非空的对象,也可以保存空值(null)。 Optional类提供了通过判断一个对象是否为空来避免空指针异常的方式。它可以在代码中替换传统的null判断,这样可以更加方便地编写代码,并且可以使代码更加健壮。 在Java中,如果一个方法返回值为null,那么在调用该方法返回值的时候,会有可能抛出NullPointerException异常。而Optional类的出现可以帮助我们避免这种情况的出现,在调用Optional类的get()方法时,如果Optional类中保存的对象不为null,就会返回该对象,否则抛出一个NoSuchElementException异常。 Optional类还提供了一些方法来简化代码,比如orElse()方法,如果Optional类中保存的对象不为null,则返回该对象,否则返回指定的default值。还有ifPresent()方法,当Optional类中保存的对象不为null时,会执行指定的代码,否则不执行。 总之,Optional类是Java 8中一个很有用的类,它可以帮助我们更加方便地处理null值,避免空指针异常的出现,并且可以简化代码。但是需要注意的是,不应该滥用Optional类,因为它并不是完美的解决方案,有时候需要对null值进行特殊处理。 ### 回答3: Java 8在语言层面上增加了一个新的类:Optional。这是一个特殊的容器对象,可以包含一个null或非null的值。 Optional的目的是解决Java中的null引用问题。在Java中,如果一个变量被赋值为null,而我们试图调用该变量所对应的方法,那么就会出现NullPointerException异常。 使用Optional可以避免这种情况的发生。如果一个变量是Optional对象,那么我们必须显式地检查该对象是否包含非null的值,才能对其进行操作。这样,在我们试图调用该变量所对应的方法之前,就可以避免空指针异常的发生。 Optional类提供了很多方法来判断是否有值、获取值、如果没有值则返回默认值等等,使得我们可以更加方便地处理空值。 下面是一些Optional类提供的方法: 1. Optional.of(T value):创建一个包含非null值的Optional对象,如果T为null,则抛出NullPointerException异常。 2. Optional.ofNullable(T value):创建一个Optional对象,如果T为null,则该对象为空。 3. Optional.empty():创建一个空的Optional对象。 4. get():如果值存在,则返回该值,否则抛出异常。 5. orElse(T other):如果值存在,则返回该值,否则返回其他默认值。 6. isPresent():返回一个boolean类型的值,表示该Optional对象是否包含值。 7. ifPresent(Consumer<? super T> consumer):如果该Optional对象包含值,则对该值执行给定的操作。 在编写Java程序时,我们应该始终努力避免使用null值。使用Optional类,可以使得我们的代码更加健壮、可读性更强。但是,过多地使用Optional可能会导致代码过于冗长,所以在使用的过程中需要权衡利弊。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值