awe*_*ell 13 java collections null functional-programming java-8
我是java中函数式编程的新手,并且想知道如何在(例如)此操作中编写代码来避免NPE:
myList.stream()
.reduce((prev, curr) -> prev.getTimestamp().isAfter(curr.getTimestamp()) ? prev : curr);
.get().getTimestamp();
Run Code Online (Sandbox Code Playgroud)
我的目的是找到列表中最新对象的时间戳.关于如何更好地收集最后一个元素的建议非常受欢迎,但我的主要问题实际上是为什么这个有效.
文档说该函数抛出NullPointerException"如果减少的结果为空":
这没关系,但是我不太明白为什么NullPointerException当这个代码运行时只包含一个元素的列表时我没有得到.prev在这种情况下,我预计会为空.我试过调试,但是当只有一个元素时,它似乎只是跨过整个lambda表达式.
Era*_*ran 21
正如reduce的JavaDoc 所说,reduce相当于:
boolean foundAny = false;
T result = null;
for (T element : this stream) {
if (!foundAny) {
foundAny = true;
result = element;
}
else
result = accumulator.apply(result, element);
}
return foundAny ? Optional.of(result) : Optional.empty();
Run Code Online (Sandbox Code Playgroud)
因此,如果Stream只有一个元素,那么循环只有一次迭代,并返回在该迭代中找到的单个元素.
所述BinaryOperator,如果将仅被应用于Stream具有至少两个元素.
更好:
Optional<Thingie> max =
myList.stream()
.reduce(BinaryOperator.maxBy(comparing(Thingie::getTimeStamp));
Run Code Online (Sandbox Code Playgroud)
这个重载reduce()返回一个Optional; 盲目拆开它get是危险的,并且冒着投掷NSEE的风险.用其中一个安全操作员打开包装,如orElse或orElseThrow.
如果您的信息流中有空值,请先使用.filter(t -> t != null).