學習完Java8的Stream方法,可能你正準備大展身手,卻發現遇到很多問題,本篇文章爲你們帶來一個findAny方法拋出java.lang.NullPointerException的場景。java
先看一下下面的代碼,猜想一下執行以後會打印什麼?bash
public class FindAnyTest {
@Test
public void test() {
List<Foo> list = new ArrayList<>();
list.add(new Foo());
// 方法一
Integer id = list.stream().map(Foo::getId).findAny().orElse(null);
System.out.println(id);
// 方法二
id = list.stream().findAny().map(Foo::getId).orElse(-1);
System.out.println(id);
}
}
class Foo {
Integer id;
public Integer getId() {
return this.id;
}
}
複製代碼
而後,執行單元測試方法,你會發現方法一拋出了異常:微信
java.lang.NullPointerException
複製代碼
若是刪除方法一,只執行方法二,則不會出現異常。爲何呢?單元測試
首先方法一種,list.stream().map(Foo::getId)經過map,對原來的Stream進行了轉換,生成了一個新的Stream,而該Stream中值是Foo的id屬性,默認爲null。針對一個元素爲null的Stream調用findAny(),固然就拋出異常了。學習
而方法二,list.stream().findAny()得到是Optional,而後對Optional調用map方法得到的是Optional,而Optional裏面的值爲null,再調用orElse方法卻不會出現問題。測試
若是對原來的整個操做進行修改,則可正常執行,那就是設置Foo對象的id默認值不爲null,或者給id賦值非null值。再次執行就不會出現異常。但這並非解決問題的根本,只是爲了演示結果。ui
原文連接:《Java8的Stream方法findAny空指針異常(NullPointerException)實例對比》this