我是靠谱客的博主 大力爆米花,最近开发中收集的这篇文章主要介绍jdk8新特性:Optional使用介绍Optional方法介绍方法举例正确使用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。

 

最后

以上就是大力爆米花为你收集整理的jdk8新特性:Optional使用介绍Optional方法介绍方法举例正确使用Optional(使用场景、旧代码改造)的全部内容,希望文章能够帮你解决jdk8新特性:Optional使用介绍Optional方法介绍方法举例正确使用Optional(使用场景、旧代码改造)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部