jdk8新特性:Optional使用介绍

Optional类,是jdk8新增类,用于优雅的解决程序中经常出现的空指针异常,且提供了多种调用方法,使代码更加干净整洁。

Optional方法介绍

方法名方法介绍方法声明
empty创建一个空的Optional对象。调用isPresent返回false,调用get抛空指针异常<T> Optional<T> empty()
of使用一个非空的值创建Optional对象。Optional.of(null)抛空指针异常<T> Optional<T> of(T value)
ofNullable可使用任意值创建Optional对象,若值为null,则创建一个空的Optional对象<T> Optional<T> ofNullable(T value)
get返回Optional对象中的值,若无值,则抛NoSuchElementException异常T get()
isPresent若Optional对象中的值存在,则返回true,否则返回falseboolean isPresent()
ifPresent若Optional对象中的值存在,则执行consumer,否则什么也不做void ifPresent(Consumer<? super T> consumer)
filter返回Optional中符合predicate的值,若值为null,则创建一个空的Optional对象Optional<T> filter(Predicate<? super T> predicate)
map对Optional中的值取出来进行操作,只有Optional中的值不为null,才执行map中操作,否则返回一个空的Optional对象【入参是一个任意值,运算后得到的值被Optional包装】<U> Optional<U> map(Function<? super T, ? extends U> mapper)
flatMap功能同map【入参必须是Optional,运算后返回的也是Optional】<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
orElse若Optional对象中有值则返回,否则返回给定值otherT orElse(T other)
orElseGet若Optional对象中有值则返回,否则触发other,并返回other调用的结果T orElseGet(Supplier<? extends T> other)
orElseThrow如果存在该值,返回包含的值,否则抛出由 Supplier 继承的异常<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X

 

方法举例

创建Optional对象

当你很确定对象不为null,可以使用of,否则尽量使用ofNullable

empty:创建一个空的Optional对象,没有任何值

Optional<Integer> optional = Optional.empty();

of:使用一个非空的值创建Optional对象

Optional<Integer> optional = Optional.of(1);

ofNullable:可使用任意值创建Optional对象,也可以是null

Optional<Integer> optional = Optional.ofNullable(null);

获取Optional中的值

get:直接获取

Optional<Integer> optional = Optional.ofNullable(1);
System.out.println(optional.get());// 打印结果1

map:

Student student = new Student("张三", "12");
Optional<Student> optional = Optional.of(student);
Optional<String> ageOptional = optional.map(Student::getAge);
System.out.println(ageOptional.get());// 打印结果12

flatMap

Student student = new Student("张三", "12");
Optional<Student> optional = Optional.of(student);
Optional<String> ageOptional = optional.flatMap(age-> Optional.of("111"));
System.out.println(ageOptional.get());// 打印结果111

条件过滤

filter

Student student = new Student("张三", "12");
Optional<Student> optional = Optional.of(student);
Optional<Student> filter = optional.filter(_student -> "12".equals(_student.getAge()));
System.out.println(filter.isPresent());// 打印结果true

判断Optional中的值是否为空

isPresent

Optional<Integer> optional = Optional.ofNullable(null);
System.out.println(optional.isPresent());// 打印结果false

Optional<Integer> optional = Optional.ofNullable(1);
System.out.println(optional.isPresent());// 打印结果true

Optional<Integer> optional = Optional.empty();
System.out.println(optional.isPresent());// 打印结果false

ifPresent

Optional<Integer> optional = Optional.empty();
optional.ifPresent(_optional -> System.out.println("111"));// 打印结果无

Optional<Integer> optional2 = Optional.of(1);
optional2.ifPresent(_optional -> System.out.println("111"));// 打印结果111

orElse

Student student = new Student("张三", "12");
Student temp = new Student("李四", "13");
Optional<Student> optional = Optional.of(student);
System.out.println(optional.orElse(temp));// 打印结果Student(name=张三, age=12)

Optional<Student> empty = Optional.empty();
System.out.println(empty.orElse(temp));// 打印结果Student(name=李四, age=13)

orElseGet

Student student = new Student("张三", "12");
Student temp = new Student("李四", "13");
Optional<Student> optional = Optional.of(student);
System.out.println(optional.orElseGet(() -> temp));// 打印结果Student(name=张三, age=12)

Optional<Student> empty = Optional.empty();
System.out.println(empty.orElseGet(() -> temp));// 打印结果Student(name=李四, age=13)

orElseThrow

Student student = new Student("张三", "12");
Optional<Student> optional = Optional.of(student);
optional.orElseThrow(() -> new IllegalArgumentException("optional为空抛异常1"));// 未抛异常

Optional<Student> empty = Optional.empty();
empty.orElseThrow(() -> new IllegalArgumentException("optional为空抛异常2"));// 抛异常

正确使用Optional(使用场景、旧代码改造)

public class Student {
    private String name;
    private String age;
    private List<School> schools;

    public static class School {
        private String schoolName;
    }
}

1、单个值判空

旧版本写法

public static String getAge(Student student) {
        if (student != null) {
            return student.getAge();
        } else {
            return "student为空";
        }
    }

新版本错误写法。  Optional不是这样用的!给你新特性是让你更优雅,这样会变的更加复杂

public static String getAge(Student student) {
        if (Optional.ofNullable(student).isPresent()) {
            return student.getAge();
        } else {
            return "student为空";
        }
    }

新版本写法1

public static String getAge(Student student) {
        return Optional.ofNullable(student)
                .map(_student -> {
                    return _student.getAge();
                })
                .orElse("student为空");
    }

新版本写法2:Lambda表达式改造

public static String getAge(Student student) {
        return Optional.ofNullable(student)
                .map(_student -> _student.getAge())// 此句使用Lambda表达式优化
                .orElse("student为空");
    }

新版本写法3:Lambda表达式双冒号缩写继续优化

public static String getAge(Student student) {
        return Optional.ofNullable(student)
                .map(Student::getAge)// 双冒号优化
                .orElse("student为空");
    }

2、对象中的对象判空

旧版本写法

public static String getSchoolName(Student student) {
        if (student != null && student.getSchools() != null) {
            for (Student.School school : student.getSchools()) {
                System.out.println(school.getSchoolName());
            }
            return "OK";
        } else {
            return "这人没上学!";
        }
    }

新版本写法

1 public static String getSchoolName(Student student) {
2         return Optional.ofNullable(student)
3                 .map(Student::getSchools)
4                 .map(_schools -> {
5                     _schools.forEach(_school -> System.out.println(_school.getSchoolName()));
6                     return "OK";
7                 })
8                 .orElse("这人没上学!");
9     }

 说明:

  1. map方法将Optional中的值取出来进行操作
  2. 当Optional中的值为null,不执行map中的操作
  3. 每一次map操作的返回值都是Optional,会将map操作得到的值装入Optional中
  4. orElse在Optional中的值为null时执行,因此在上述代码的多次map操作中,每次返回的Optional任意一个为null,都执行最终的orElse

---------------------------------------------------------------------------------------------

  • 第2行中Optional中放的对象为student,因此第三行进行map操作,可以获取student中的属性值,若student==null,则不执行map,直接执行最终的orElse
  • 若执行了第3行的map,则将student中的school属性装入Optional中
  • 第4行继续执行map,而此时Optional中的对象为school,若school==null,则不执行此行map,直接执行最终的orElse
  • 若执行了第4行的map,则代表school不为空,并对school对象中的属性进行操作,整个过程优雅而不失体面,nice。

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值