近年來,隨着Java的8流工作時,我碰到一個NullPointerException
上降低操作來與下面的測試案例工作時:NPE的Java流減少操作
private static final BinaryOperator<Integer> sum = (a, b) -> {
if (a == null) return b;
if (b == null) return a;
return Integer.sum(a, b);
};
List<Integer> 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
在檢查減少操作時,我遇到了執行減少操作的類:
class ReducingSink implements AccumulatingSink<T, Optional<T>, 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<T> get() {
return empty ? Optional.empty() : Optional.of(state);
}
@Override
public void combine(ReducingSink other) {
if (!other.empty)
accept(other.state);
}
}
在上面的代碼中,如果布爾型empty
爲假,則看到get()
方法返回可選值,在我的情況下,該值爲false,但state
爲空,因此Optional.of(null)
將拋出NullPointerException
。在我的情況下,我有一個二進制運算符,它允許null
。
所以我覺得代碼
return empty ? Optional.empty() : Optional.of(state);
應改爲
return empty || state == null ? Optional.empty() : Optional.of(state);
正如我的二進制運算符(其具有減少的任務),並且是好的與null
。
'Optional.ofNullable'如何?無論如何,你的例子看起來不正確,因爲你在'BinaryOperator'中使用'List '。 –
Pshemo
@Pshemo'ReducingSink'是一個內部jdk類 – Eugene
反正 - @ Pshemo是對的 - 這個例子編譯得不好:-) –