P14-15
程序清单1-3 optional/OptionalTest.java
- 代码
- 项目结构
- 分析
- 重要API
1.代码
import java.io.*;
import java.nio.charset.*;
import java.nio.file.*;
import java.util.*;
public class OptionalTest {
public static void main(String[] args) throws IOException {
//取出words.txt中所有内容,并将之拆分为单词赋给wordList
String contents = new String(Files.readAllBytes(Paths.get("src/第1章流库/Words.txt")), StandardCharsets.UTF_8);
List<String> wordList = Arrays.asList(contents.split("\\PL+"));
//找到wordList中第一个包含fred字符串的元素并打印
Optional<String> optionalValue = wordList.stream().filter(s -> s.contains("fred")).findFirst();
System.out.println(optionalValue.orElse("No word") + " contains fred");
//创建空Optional并调用orElse输出other(在这里即result)的内容"N/A"
Optional<String> optionalString = Optional.empty();
String result = optionalString.orElse("N/A");
System.out.println("result:" + result);
//将调用other产生的结果赋给result并打印
result = optionalString.orElseGet(() -> Locale.getDefault().getDisplayName());
System.out.println("result:" + result);
//调用orElseThrow,在Optional为空时抛出调用exceptionSupplier的结果,并打印异常栈轨迹
try{
result = optionalString.orElseThrow(IllegalStateException::new);
System.out.println("result:" + result);
}
catch(Throwable t){
t.printStackTrace();
}
//找到wordList中第一个包含red字符串的元素,如果该元素存在就打印
optionalValue = wordList.stream().filter(s -> s.contains("red")).findFirst();
optionalValue.ifPresent(s -> System.out.println(s + " contains red"));
//创建一个Hashset对象results,将optionalValue里的值(如果值存在的话)传入results
Set<String> results = new HashSet<>();
optionalValue.ifPresent(results::add);
//将Optional的值传入results,并将results::add的返回值(Boolean类型)存入added并打印
Optional<Boolean> added = optionalValue.map(results::add);
System.out.println(added);
//以下请参考“分析”中两个静态方法的部分,以及flatMap API
System.out.println (inverse(4.0).flatMap(OptionalTest::squareRoot));
System.out.println (inverse(-1.0).flatMap(OptionalTest::squareRoot));
System.out.println (inverse(0.0).flatMap(OptionalTest::squareRoot));
Optional<Double> result2 = Optional.of (-4.0)
.flatMap (OptionalTest::inverse).flatMap (OptionalTest::squareRoot);
System.out.println (result2);
}
private static Optional<Double> inverse(Double x) {
return x == 0 ? Optional.empty () : Optional.of (1 / x) ;
}
private static Optional<Double> squareRoot(Double x) {
return x < 0 ? Optional.empty () : Optional.of (Math.sqrt (x));
}
}
Words.txt里随便写几行字符就好了,这里随便提供一个:
abcdefghijklmnopqrstuvwxyz asd efg hij klm ChineseWordsAreNotAvailable
abcdfredefg
abcdefghijklm!opqrstuvwxyz
2.项目结构
3.分析
1.程序目的
演示Optional API的使用方式。
2.代码片段
先讲一下两个静态方法:
private static Optional<Double> inverse(Double x) {
return x == 0 ? Optional.empty () : Optional.of (1 / x) ;
}
inverse(Double x)
方法:如果传入参数x为0则返回空Optional,不为0则返回具有给定值1/x的Optional。
private static Optional<Double> squareRoot(Double x) {
return x < 0 ? Optional.empty () : Optional.of (Math.sqrt (x));
}
squareRoot(Double x)
方法:如果传入参数x小于0则返回空Optional,不为0则返回具有给定值√x的Optional。
回到main函数:
(在这里仅分析部分较复杂的代码块)
1st PART:
找到wordList中第一个包含fred字符串的元素并打印,若找不到则打印No word。
Optional<String> optionalValue = wordList.stream()
.filter(s -> s.contains("fred")).findFirst();
System.out.println(optionalValue.orElse("No word") + " contains fred");
stream
方法返回用wordList
列表创建的流,filter方法返回一个包含旧流中部分元素的新流。这些元素是旧流中包含fred的字符串元素。
findFirst
方法返回新流中第一个元素。
orElse
方法:产生这个Optional的值,若该Optional为空则产生other
(在这里即”No word”)。
2nd PART:
将调用other产生的结果赋给result并打印。
result = optionalString.orElseGet(() -> Locale.getDefault().getDisplayName());
System.out.println("result:" + result);
java.util.Locale.getDefault()
:返回默认区域设置的Java虚拟机实例。
Locale.getDefault().getDisplayName()
请参考java.util.Locale.getDisplayName()方法实例
3rd PART:
//创建一个Hashset对象results,将optionalValue里的值(如果值存在的话)传入results
Set<String> results = new HashSet<>();
optionalValue.ifPresent(results::add);
//将Optional的值传入results,并将results::add的返回值(Boolean类型)存入added并打印
Optional<Boolean> added = optionalValue.map(results::add);
System.out.println(added);
有关HashSet
请参考Java集合框架系列——HashSet
results::add
是将optionalValue
中的元素通过add
方法传入results
中。
optionalValue.map(results::add)
尝试将optionalValue
中元素传入results
,但由于已经被传入过,而HashSet
集合不允许重复元素,因而添加不成功。于是results::add
返回false
,最终打印added
得到Optional[false]
。
4.重要API
-
T orElse(T other)
产生这个Optional的值,或者在该Optional为空时,产生other。T orElseGet(Supplier<? extends T>other)
产生这个Optional的值,或者在该Optional为空时,产生调用other的结果。<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
产生这个Optional的值,或者在该Optional为空时,抛出调用exceptionSupplier的结果。void ifPresent(Consumer<? super T> consumer)
如果该Optional不为空,那么就将它的值传递给consumer。boolean ifPresent()
如果该Optional不为空,则返回true。<U> Optional<U> map(Function<? super T,? extends U> mapper
产生将该Optional的值传递给mapper后的结果,只要这个Optional不为空且结果不为null,否则产生一个空Optional。<U> Optional<U> flatmap(Function<? super T,Optional<U>> mapper
产生将mapper应用于当前的Optional值所产生的结果,或者在当前Optional为空时,返回一个空Optional。static <T> Optional<T> of(T value)
static <T> Optional<T> ofNullable(T value)
产生一个具有给定值的Optional。如果value为null,那么第一个方法会抛出一个NullPointerException对象,而第二个方法会产生一个空Optional。static <T> Optional<T> empty()
产生一个空Optional。
java.util.Optional 8
如有谬误或不完善之处,恳请斧正。