当我们的 Java 程序中需要处理 null 值的时候,Java Optional 是一个非常有用的工具类,它在 Java 8 中被引入,为我们提供了更好的解决方案。本文将介绍 Java Optional 的用法和示例代码。
一、什么是 Java Optional
Java Optional 是一个可以包含 null 或者非 null 值的容器。它是一个类,提供了一些方法用于安全地处理可能为 null 的值。
Java Optional 类有两个子类:Optional 和 OptionalDouble。Optional 是一个泛型类,可以包含任意类型的对象。而 OptionalDouble 是一个针对 double 类型的特殊 Optional 类。除此之外,Java 还提供了 OptionalInt 和 OptionalLong 两个类,用于处理 int 和 long 类型的 null 值。
在 Java 8 之前,我们可能经常看到一个空值异常(NullPointerException)在我们的代码中出现。这通常是因为我们的代码试图使用一个空对象引用。例如:
String name = null;
System.out.println(name.length());
在这个例子中,变量 name 为空,因此我们尝试调用 length() 方法时会出现空指针异常。
为了解决这个问题,Java 8 引入了 Optional 类型。
Optional 是一个包含可选值的对象容器,可以防止我们在应用程序中使用 null 值。Optional 对象可以包含一个非空值,也可以是空的。
二、如何使用 Optional?
Optional 类型有几种不同的用法,其中一些是:
创建 Optional 对象
我们可以使用静态方法 of() 创建一个 Optional 对象,该对象包含一个非空值。
例如,要创建一个包含字符串 "hello" 的 Optional 对象,可以使用以下代码:
Optional<String> optional = Optional.of("hello");
我们还可以使用静态方法 ofNullable() 创建 Optional 对象。与 of() 不同的是,如果传递的值为空,ofNullable() 方法将创建一个空的 Optional 对象。
Optional<String> optional = Optional.ofNullable(null);
检查 Optional 对象是否包含值
我们可以使用 isPresent() 方法检查 Optional 对象是否包含值。如果包含,isPresent() 方法将返回 true,否则返回 false。
Optional<String> optional = Optional.of("hello");
if (optional.isPresent()) {
System.out.println("value is present");
} else {
System.out.println("value is absent");
}
获取 Optional 对象的值
我们可以使用 get() 方法从 Optional 对象中获取值。如果 Optional 对象不包含值,get() 方法将抛出 NoSuchElementException 异常。
Optional<String> optional = Optional.of("hello");
String value = optional.get();
System.out.println(value);
避免使用 get() 方法,因为这可能会引发异常。相反,我们可以使用 orElse() 方法提供一个默认值,以便在 Optional 对象不包含值时返回。
Optional<String> optional = Optional.ofNullable(null);
String value = optional.orElse("default");
System.out.println(value);
链式调用 Optional 对象
Optional 类型还提供了很多方便的方法来对 Optional 对象进行链式调用。例如,我们可以使用 map() 方法将 Optional 对象中的值转换为其他类型。
Optional<String> optional = Optional.of("hello");
Optional<Integer> length = optional.map(String::length);
System.out.println(length.get());
我们还可以使用 flatMap() 方法将 Optional 对象转换为另一个 Optional 对象。
Optional<String> optional = Optional.of("hello");
Optional<String> result = optional.flatMap(value -> Optional.of(value.toUpperCase()));
System.out.println(result.get());
三、Java Optional 的常用方法
Java Optional 类提供了很多实用的方法,这里我们介绍其中的一些。
ofNullable() 方法
ofNullable() 方法接受一个对象作为参数,如果该对象为 null,它会返回一个空的 Optional 对象。否则,它会将对象包装在 Optional 容器中。
下面是一个示例代码:
String str = null;
Optional<String> optional = Optional.ofNullable(str);
isPresent() 方法
isPresent() 方法用于检查 Optional 对象中是否存在非 null 的值。如果存在,它会返回 true,否则返回 false。
下面是一个示例代码:
String str = "Hello World";
Optional<String> optional = Optional.ofNullable(str);
if (optional.isPresent()) {
System.out.println("String value: " + optional.get());
}
ifPresent() 方法
ifPresent() 方法用于检查 Optional 对象中是否存在非 null 的值。如果存在,它会执行指定的操作,否则不执行。
下面是一个示例代码:
String str = "Hello World";
Optional<String> optional = Optional.ofNullable(str);
optional.ifPresent(s -> System.out.println("String value: " + s));
orElse() 方法
orElse() 方法用于在 Optional 对象为空时返回一个默认值。如果 Optional 对象不为空,它会返回 Optional 对象中的值。
下面是一个示例代码:
String str = null;
String defaultValue = "Default Value";
String value = Optional.ofNullable(str).orElse(defaultValue);
System.out.println("String value: " + value);
map() 方法
map() 方法用于将 Optional 对象中的值通过指定的映射函数转换成另外一种类型。
下面是一个示例代码:
String str = "Hello World";
Optional<String> optional = Optional.ofNullable(str);
Optional<Integer> lengthOptional = optional.map(String::length);
lengthOptional.ifPresent(length -> System.out.println("String length: " + length));
filter() 方法
filter() 方法用于对 Optional 对象中的值进行过滤。如果满足指定的条件,它会返回 Optional 对象,否则返回空的 Optional 对象。
下面是一个示例代码:
import java.util.Optional;
class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class OptionalFilterExample {
public static void main(String[] args) {
User user = new User("John", 30);
Optional<User> optionalUser = Optional.of(user);
Optional<User> filteredUser = optionalUser.filter(u -> u.getAge() >= 18);
if (filteredUser.isPresent()) {
System.out.println(filteredUser.get().getName() + " is an adult.");
} else {
System.out.println("No adult user found.");
}
}
}