了解 Java Optional:如何更优雅地处理空值情况

465 阅读4分钟

什么是Optional?

Java中Optional类是一个容器类,可以包含一个非空值或者表示什么都不包含。它消除了代码中的null检查,从而使代码更加健壮和易于维护

Optional的好处是什么?

1.在使用一个值之前,需要判断它是否为null或undefined,以避免出现NullPointerException或UndefinedReferenceError等运行时错误。

2.使用Optional可以在类型层面上表示一个值可能不存在,从而提供一种更安全的处理这种情况的方式。

3.简化代码逻辑。使用Optional可以简化代码逻辑,避免过多的null检查和条件分支,使代码更加清晰简洁。

4.支持函数式编程风格。Optional是函数式编程中的一种重要概念,可以方便地进行链式调用、过滤、映射等操作,提高代码的表达能力和可读性。

Optional常用方法

以下是一些常用的Optional方法:

  • of: 创建一个包含给定非null值的Optional
Optional<String> str = Optional.of("hello");
  • ofNullable: 创建一个空的Optional或者包含指定的值
Optional<String> str1 = Optional.ofNullable(null);
Optional<String> str2 = Optional.ofNullable("world");
  • orElse: 如果存在值,则返回它,否则返回默认值
Optional<String> str1 = Optional.ofNullable(null);
String result1 = str1.orElse("default");

Optional<String> str2 = Optional.ofNullable("hello");
String result2 = str2.orElse("default");
  • orElseGet: 如果存在值,则返回它,否则返回通过Supplier提供的默认值
Optional<String> str1 = Optional.ofNullable(null);
String result1 = str1.orElseGet(() -> "default");

Optional<String> str2 = Optional.ofNullable("hello");
String result2 = str2.orElseGet(() -> "default");
  • orElseThrow: 如果存在值,则返回它,否则抛出通过Supplier提供的异常
Optional<String> str1 = Optional.ofNullable(null);
String result1 = str1.orElseThrow(() -> new RuntimeException("value is null"));

Optional<String> str2 = Optional.ofNullable("hello");
String result2 = str2.orElseThrow(() -> new RuntimeException("value is null"));
  • isPresent: 如果存在值,则返回true,否则返回false
Optional<String> str1 = Optional.ofNullable(null);
boolean result1 = str1.isPresent();

Optional<String> str2 = Optional.ofNullable("hello");
boolean result2 = str2.isPresent();
  • ifPresent: 如果存在值,则执行指定的操作
Optional<String> str1 = Optional.ofNullable(null);
str1.ifPresent(System.out::println);

Optional<String> str2 = Optional.ofNullable("hello");
str2.ifPresent(System.out::println);
  • map: 如果存在值,则对其执行提供的Function操作
Optional<String> str1 = Optional.ofNullable(null);
Optional<Integer> result1 = str1.map(String::length);

Optional<String> str2 = Optional.ofNullable("hello");
Optional<Integer> result2 = str2.map(String::length);
  • flatMap: 如果存在值,则对其执行提供的Function操作,然后返回Optional类型的结果
Optional<String> str1 = Optional.ofNullable(null);
Optional<String> result1 = str1.flatMap(s -> Optional.ofNullable(s.toUpperCase()));

Optional<String> str2 = Optional.ofNullable("hello");
Optional<String> result2 = str2.flatMap(s -> Optional.ofNullable(s.toUpperCase()));
  • filter: 如果存在值并且满足提供的Predicate条件,则返回包含该值的Optional,否则返回一个空的Optional
Optional<String> str1 = Optional.ofNullable(null);
Optional<String> result1 = str1.filter(s -> s.length() > 3);

Optional<String> str2 = Optional.ofNullable("hello");
Optional<String> result2 = str2.filter(s -> s.length() > 3);
  • get: 如果存在值,则返回它,否则抛出NoSuchElementException异常
Optional<String> str1 = Optional.ofNullable(null);
String result1 = str1.get(); // throws NoSuchElementException

Optional<String> str2 = Optional.ofNullable("hello");
String result2 = str2.get();

这些方法可以帮助我们更好地使用Optional类。需要注意的是,应该谨慎使用get()方法,因为如果Optional为空,则会抛出异常。建议在使用get()方法之前,先使用isPresent()方法判断Optional是否存在值。

另外,还有一些常用的Optional方法。

  • ifPresentOrElse: 如果存在值,则执行指定的操作,否则执行提供的Runnable操作
Optional<String> str1 = Optional.ofNullable(null);
str1.ifPresentOrElse(System.out::print, () -> System.out.println("value is null"));

Optional<String> str2 = Optional.ofNullable("hello");
str2.ifPresentOrElse(System.out::println, () -> System.out.println("value is null"));

ifPresentOrElse方法可以让我们在Optional对象为空时执行一些操作,避免了使用isPresent方法再进行一次判断的麻烦。

除此之外,还有一些方法可以与Optional类一起使用,更好地完成一些常见的编程任务。

  • orElseThrow: 如果存在值,则返回它,否则抛出通过Supplier提供的异常
Optional<String> str1 = Optional.ofNullable(null);
String result1 = str1.orElseThrow(() -> new RuntimeException("value is null"));

Optional<String> str2 = Optional.ofNullable("hello");
String result2 = str2.orElseThrow(() -> new RuntimeException("value is null"));
  • stream: 如果存在值,则返回一个包含该值的Stream,否则返回一个空的Stream
Optional<String> str1 = Optional.ofNullable(null);
Stream<String> stream1 = str1.stream();

Optional<String> str2 = Optional.ofNullable("hello");
Stream<String> stream2 = str2.stream();
  • ifPresentOrElse: 如果存在值,则执行指定的操作,否则执行提供的Runnable操作
Optional<String> str1 = Optional.ofNullable(null);
str1.ifPresentOrElse(System.out::println, () -> System.out.println("value is null"));

Optional<String> str2 = Optional.ofNullable("hello");
str2.ifPresentOrElse(System.out::println, () -> System.out.println("value is null"));
  • orElseGet: 如果存在值,则返回它,否则返回通过Supplier提供的默认值
Optional<String> str1 = Optional.ofNullable(null);
String result1 = str1.orElseGet(() -> "default");

Optional<String> str2 = Optional.ofNullable("hello");
String result2 = str2.orElseGet(() -> "default");

这些方法可以让我们更加方便地使用Optional类,提高代码的可读性和可维护性。需要注意的是,orElseThrow方法可以抛出指定的异常,所以在使用时需要谨慎考虑异常处理方案。此外,stream方法可以将Optional对象转换为Stream对象,方便我们进行流式处理。最后,orElseGet方法可以通过Supplier提供默认值,避免了每次都需要写默认值的麻烦。