java8中Optional类的使用

一、简述

Optional类是java8中引入的一个非常有用的类,主要用处是解决编程中的空指针异常,本质上,这是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空。Optional 是 Java 实现函数式编程的强劲一步,并且帮助在范式中实现。

二、场景

在java8之前,任何访问对象方法或属性的调用都有可能导致空指针异常,例如:


String isocode = user.getAddress().getCountry().getIsocode().toUpperCase();

这行代码如果我们需要确保不触发异常,我们就要写成:


if (user != null) {
    Address address = user.getAddress();
    if (address != null) {
        Country country = address.getCountry();
        if (country != null) {
            String isocode = country.getIsocode();
            if (isocode != null) {
                isocode = isocode.toUpperCase();
            }
        }
    }
}

这样看起来太繁琐了,而且看起来很low,那么如何才能简洁的实现以上判断呢?

三、Optional容器类的常用方法


Optional.of(T t):创建一个Optional实例
Optional.empty():创建一个空的Optional实例
Optional.ofNullable(T t):若t不为null,创建Optional实列,否则创建空实例
isPresent():判断是否包含值
orElse(T t):如果调用对象包含值,返回该值,否则返回t
orElseGet(Supplier s):如果调用对象包含值,返回该值,否则返回s获取的值
map(Function f):如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
flatMap(Function mapper):与map类似,要求返回值必须是Optional

1.创建Optional实例

使用empty()创建空实例


Optional<User> emptyOpt = Optional.empty();

尝试访问emptyOpt变量的值会导致NoSuchElementException

使用of()或ofNullable()方法创建包含值的Optional,不同之处在于:如果你把 null 值作为参数传递进去,of() 方法会抛出 NullPointerException


Optional<User> opt1 = Optional.of(user);
Optional<User> opt1 = Optional.ofNullable(user);

2.访问Optional对象的值

使用get()方法获取Optional的值


Optional<User> opt1 = Optional.of(user);
User tmp = opt1.get();

3.返回默认值

orElse()方法可以在创建实例时就指定返回的默认值


User user = null;
User user2 = new User("anna@gmail.com", "1234");
User result = Optional.ofNullable(user).orElse(user2);

因为user是空,所以此时我们想获取result的值的话会得到user2

我们也可以使用orElseGet(),如果没有值,它会执行作为参数传入的 Supplier(供应者) 函数式接口,并将返回其执行结果


User result = Optional.ofNullable(user).orElseGet( () -> user2);

不同的是使用orElse的话无论创建的值是否为空,都会orElse里的代码,如果里面有创建新的实例,这会对性能产生很大影响

另外我们可以使用orElseThrow(),它会在对象为空的时候抛出异常,而不是返回备选的值


User result = Optional.ofNullable(user)
        .orElseThrow( () -> new IllegalArgumentException());
        

此时如果user为空,会抛出我们定义的异常IllegalArgumentException

4.转换值

我们可以使用map方法,将 Optional里的元素进行转换


User user = new User("anna@gmail.com", "1234");
String email = Optional.ofNullable(user)
        .map(u -> u.getEmail()).orElse("default@gmail.com");
        

注意无论是user为null,还是user里的Email为空,都会触发返回orElse里的默认值,这也就Optional的map操作的链式调用的精髓,我们可以不断的接着写map,无需一次次地判断是否为空

5.过滤值

filter()接受一个Predicate参数,返回测试结果为 true 的值

用法和stream的filter一模一样,例如我们可以检查用户的邮箱是否带@


User user = new User("anna@gmail.com", "1234");
Optional<User> result = Optional.ofNullable(user)
        .filter(u -> u.getEmail() != null && u.getEmail().contains("@"));
        

6.对原来if的改进

对于User类我们对其进行重构,使其getter方法返回Optional类


public class User {
    private Address address;

    public Optional<Address> getAddress() {
        return Optional.ofNullable(address);
    }

    // ...
}
public class Address {
    private Country country;

    public Optional<Country> getCountry() {
        return Optional.ofNullable(country);
    }

    // ...
}

之前冗杂的if判断我们就可以改成这样:


String result = Optional.ofNullable(user)
        .flatMap(u -> u.getAddress())
        .flatMap(a -> a.getCountry())
        .map(c -> c.getIsocode())
        .orElse("default");
        

也可以简写成这样:


String result = Optional.ofNullable(user)
  .flatMap(User::getAddress)
  .flatMap(Address::getCountry)
  .map(Country::getIsocode)
  .orElse("default");
  

四、代码示例

 public static void main(String[] args) {
        test1();

    }

    //1、Optional.of(T t):创建一个Optional实例
    public static void test1() {
        Optional<User> op = Optional.of(new User());
        User emp = op.get();
        System.out.println(emp);
    }
运行结果:
User{id=null, name='null', sex='null', age=null, createDt='null', updateDt='null'}
 //2、Optional.empty():创建一个空的Optional实例
    public static void test2() {
        Optional<User> op = Optional.empty();
        System.out.println(op.get());
    }
运行结果:
Exception in thread "main" java.util.NoSuchElementException: No value present
	at java.util.Optional.get(Optional.java:135)
	at org.sang.test.OptionalDemo.test2(OptionalDemo.java:28)
	at org.sang.test.OptionalDemo.main(OptionalDemo.java:14)

语法说明
标题文本样式列表图片链接目录代码片表格注脚注释自定义列表LaTeX 数学公式插入甘特图插入UML图插入Mermaid流程图插入Flowchart流程图插入类图快捷键
代码片复制

下面展示一些 内联代码片

// A code block
var foo = 'bar';
 //3、Optional.ofNullable(T t):若t不为null,创建Optional实列,否则创建空实例
    public static void test3() {
        Optional<User> op = Optional.ofNullable(null); //不能传null
        if (op.isPresent()) {
            System.out.println(op.get());
//            System.out.println(op1.get());
        }
        System.out.println("-------------------------------------------------------");
        User emp = op.orElse(new User(1,"zhangsan", "man",18));
        System.out.println(emp);
        System.out.println("-------------------------------------------------------");
        User emp1 = op.orElseGet(() -> new User());
        System.out.println(emp1);

    }
运行结果:
User{id=1, name='zhangsan', sex='man', age=18, createDt='null', updateDt='null'}
-------------------------------------------------------
User{id=null, name='null', sex='null', age=null, createDt='null', updateDt='null'}
 public static void test4() {
        Optional<User> op = Optional.ofNullable(new User(1,"zhangsan", "man",18));
//        Optional<String> s = op.map((e) -> e.getName());
//        System.out.println(s.get());
        //多一步判空
        Optional<String> s = op.flatMap((e) -> Optional.of(e.getName()));
        System.out.println(s.get());

    }
运行结果:
zhangsan
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
OptionalJava 8引入的一个用于解决空指针异常问题的容器。它可以包含一个非空的值,也可以表示为空。Optional的设计目的是为了避免在代码频繁使用null值,从而提高代码的可读性和健壮性。 使用Optional可以有效地处理可能为空的值,避免出现NullPointerException。它提供了一系列方法来判断Optional对象是否包含值,如果有值则可以通过get()方法获取该值,或者使用orElse()方法指定一个默认值。 下面是一个示例代码,演示了如何使用Optional: ```java Optional<String> optionalValue = Optional.of("Hello World"); if (optionalValue.isPresent()) { String value = optionalValue.get(); System.out.println(value); } else { System.out.println("Value is absent"); } String defaultValue = optionalValue.orElse("Default Value"); System.out.println(defaultValue); ``` 在上面的代码,我们首先使用`Optional.of()`方法创建了一个包含非空值的Optional对象。然后通过`isPresent()`方法判断Optional对象是否包含值,如果有值则通过`get()`方法获取该值并输出。如果Optional对象为空,则输出"Value is absent"。 接下来使用`orElse()`方法指定了一个默认值,并输出该默认值。如果Optional对象包含值,则输出原始值;如果Optional对象为空,则输出指定的默认值。 使用Optional可以有效地避免空指针异常,并提高代码的可读性和健壮性。它在编写Java代码时是一个非常有用的工具。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初夏0811

你的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值