最近,在使用
Java 8流时,我在使用以下测试用例时遇到了对reduce操作的NullPointerException:
private static final BinaryOperator sum = (a, b) -> {
if (a == null) return b;
if (b == null) return a;
return Integer.sum(a, b);
};
List s = new ArrayList<>();
s.add(null);
s.add(null);
s.add(null);
Integer i = s.stream().reduce(sum).orElse(null);
// throws NPE
Integer i = s.stream().reduce(sum).orElse(2);
// throws NPE
Integer i = s.stream().reduce(null,(a, b)->null);
// returns a value i.e null
或者:
Integer i = s.stream().filter(Objects::nonNull).reduce(Integer::sum).orElse(null);
// returns a value i.e null
检查reduce操作后,我遇到了执行reduce操作的类:
class ReducingSink implements AccumulatingSink, ReducingSink> {
private boolean empty;
private T state;
public void begin(long size) {
empty = true;
state = null;
}
@Override
public void accept(T t) {
if (empty) {
empty = false;
state = t;
} else {
state = operator.apply(state, t);
}
}
@Override
public Optional get() {
return empty ? Optional.empty() : Optional.of(state);
}
@Override
public void combine(ReducingSink other) {
if (!other.empty)
accept(other.state);
}
}
在上面的代码中,您看到如果boolean empty为false,则get()方法返回一个可选值,在我的情况下,该值为false但state为null,因此Optional.of(null)抛出NullPointerException.在我的情况下,我有一个允许null的二元运算符.
所以我认为代码
return empty ? Optional.empty() : Optional.of(state);
应改为
return empty || state == null ? Optional.empty() : Optional.of(state);
作为我的二元运算符(具有减少的任务)并且可以使用null.