原文: https://beginnersbook.com/2017/10/java-8-optional-class/
在 Java 8 中,我们在java.util
包中新引入了Optional
类。引入此类是为了避免在我们的代码中不执行空检查时经常遇到的NullPointerException
。使用这个类,我们可以很容易地检查变量是否具有null
值,通过这样做,我们可以避免NullPointerException
。在本指南中,我们将了解如何使用Optional
类以及此类的各种方法的用法。
在我们看到Optional
类的示例之前,让我们看看当我们不使用Optional
类并且不执行null
检查时会发生什么。
在这个例子中,我们没有将值赋给String str
,我们试图从中获取子串。由于str
中没有值,程序抛出NullPointerException
。
public class Example {
public static void main(String[] args) {
String[] str = new String[10];
//Getting the substring
String str2 = str[9].substring(2, 5);
//Displaying substring
System.out.print(str2);
}
}
输出:
Exception in thread "main" java.lang.NullPointerException
at Example.main(Example.java:5)
Optional
类的Optional.ofNullable()
方法,如果给定对象有值,则返回非空Optional
,否则返回空Optional
。
我们可以使用isPresent()
方法检查返回的Optional
值是空还是非空。
//Importing Optional class
import java.util.Optional;
public class Example {
public static void main(String[] args) {
String[] str = new String[10];
Optional<String> isNull = Optional.ofNullable(str[9]);
if(isNull.isPresent()){
//Getting the substring
String str2 = str[9].substring(2, 5);
//Displaying substring
System.out.print("Substring is: "+ str2);
}
else{
System.out.println("Cannot get the substring from an empty string");
}
str[9] = "AgraIsCool";
Optional<String> isNull2 = Optional.ofNullable(str[9]);
if(isNull2.isPresent()){
//Getting the substring
String str2 = str[9].substring(2, 5);
//Displaying substring
System.out.print("Substring is: "+ str2);
}
else{
System.out.println("Cannot get the substring from an empty string");
}
}
}
输出:
Cannot get the substring from an empty string
Substring is: raI
在上面的例子中,我们已经看到通过使用isPresent()
方法,我们可以检查特定的Optional
对象(或实例)是空还是非空。
Optional
类中还有另一种方法,只有在给定的Optional
对象为非空时才执行,方法为ifPresent()
。让我们看一个例子来理解差异。
//Importing Optional class
import java.util.Optional;
public class Example {
public static void main(String[] args) {
//Creating Optional object from a String
Optional<String> GOT = Optional.of("Game of Thrones");
//Optional.empty() creates an empty Optional object
Optional<String> nothing = Optional.empty();
/* isPresent() method: Checks whether the given Optional
* Object is empty or not.
*/
if (GOT.isPresent()) {
System.out.println("Watching Game of Thrones");
}
else {
System.out.println("I am getting Bored");
}
/* ifPresent() method: It executes only if the given Optional
* object is non-empty.
*/
//This will print as the GOT is non-empty
GOT.ifPresent(s -> System.out.println("Watching GOT is fun!"));
//This will not print as the nothing is empty
nothing.ifPresent(s -> System.out.println("I prefer getting bored"));
}
}
输出:
Watching Game of Thrones
Watching GOT is fun!
如果该对象为空,则这两个方法orElse()
和orElseGet()
返回Optional
对象的值,如果该对象为空,则返回作为参数传递给此方法的默认值。
//Importing Optional class
import java.util.Optional;
public class Example {
public static void main(String[] args) {
//Creating Optional object from a String
Optional<String> GOT = Optional.of("Game of Thrones");
//Optional.empty() creates an empty Optional object
Optional<String> nothing = Optional.empty();
//orElse() method
System.out.println(GOT.orElse("Default Value"));
System.out.println(nothing.orElse("Default Value"));
//orElseGet() method
System.out.println(GOT.orElseGet(() -> "Default Value"));
System.out.println(nothing.orElseGet(() -> "Default Value"));
}
}
输出:
Game of Thrones
Default Value
Game of Thrones
Default Value
在这个例子中,我们将看到Optional
如何与map
和flatMap
一起使用。
//Importing Optional class
import java.util.Optional;
public class Example {
public static void main(String[] args) {
//Creating Optional object from a String
Optional<String> GOT = Optional.of("Game of Thrones");
//Optional.empty() creates an empty Optional object
Optional<String> nothing = Optional.empty();
System.out.println(GOT.map(String::toLowerCase));
System.out.println(nothing.map(String::toLowerCase));
Optional<Optional<String>> anotherOptional = Optional.of(Optional.of("BreakingBad"));
System.out.println("Value of Optional object"+anotherOptional);
System.out.println("Optional.map: "
+anotherOptional.map(gender -> gender.map(String::toUpperCase)));
//Optional<Optional<String>> -> flatMap -> Optional<String>
System.out.println("Optional.flatMap: "
+anotherOptional.flatMap(gender -> gender.map(String::toUpperCase)));
}
}
输出:
Optional[game of thrones]
Optional.empty
Value of Optional objectOptional[Optional[BreakingBad]]
Optional.map: Optional[Optional[BREAKINGBAD]]
Optional.flatMap: Optional[BREAKINGBAD]
在这个例子中,我们将看到Optional
如何与过滤器一起使用。要阅读有关过滤器的信息,请参阅本指南: Java 过滤器。
有关过滤器的更多教程:
//Importing Optional class
import java.util.Optional;
public class Example {
public static void main(String[] args) {
//Creating Optional object from a String
Optional<String> GOT = Optional.of("Game of Thrones");
/* Filter returns an empty Optional instance if the output doesn't
* contain any value, else it returns the Optional object of the
* given value.
*/
System.out.println(GOT.filter(s -> s.equals("GAME OF THRONES")));
System.out.println(GOT.filter(s -> s.equalsIgnoreCase("GAME OF THRONES")));
}
}
输出:
Optional.empty
Optional[Game of Thrones]
参考文献: