stream簡介
我們先來看看java里面是怎么定義stream的:
a sequence of elements supporting sequential and parallel aggregate operations.
我們來解讀一下上面的那句話:
- stream是元素的集合,這點讓stream看起來用些類似iterator;
- 可以支持順序和并行的對原stream進行匯聚的操作;
大家可以把stream當成一個高級版本的iterator。原始版本的iterator,用戶只能一個一個的遍歷元素并對其執行某些操作;高級版本的stream,用戶只要給出需要對其包含的元素執行什么操作,比如“過濾掉長度大于10的字符串”、“獲取每個字符串的首字母”等,具體這些操作如何應用到每個元素上,就給stream就好了!(這個秘籍,一般人我不告訴他:))大家看完這些可能對stream還沒有一個直觀的認識,莫急,咱們來段代碼。
1
2
3
|
//lists是guava中的一個工具類 list<integer> nums = lists.newarraylist( 1 , null , 3 , 4 , null , 6 ); nums.stream().filter(num -> num != null ).count(); |
上面這段代碼是獲取一個list中,元素不為null的個數。這段代碼雖然很簡短,但是卻是一個很好的入門級別的例子來體現如何使用stream,正所謂“麻雀雖小五臟俱全”。
引子
今天下午遇到一個npe,如下圖所示
跟了下源碼,最后跟到referencepipeline#193行,應該是調用apply的時候,入參u為null,從而觸發了空指針異常。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@override @suppresswarnings ( "unchecked" ) public final <r> stream<r> map(function<? super p_out, ? extends r> mapper) { objects.requirenonnull(mapper); return new statelessop<p_out, r>( this , streamshape.reference, streamopflag.not_sorted | streamopflag.not_distinct) { @override sink<p_out> opwrapsink( int flags, sink<r> sink) { return new sink.chainedreference<p_out, r>(sink) { @override public void accept(p_out u) { downstream.accept(mapper.apply(u)); } }; } }; } |
為了驗證我的想法,我寫了如下的測試例子:
1
2
3
4
5
6
7
8
|
public static void main(string[] args) { list< long > res = arrays.aslist(1l, 2l, null ); res.stream().map(userreadserviceimpl::get).collect(collectors.tolist()); } public static long get( long userid) { return userid; } |
最佳實踐
- 在streams開始和結束之前,都需要避免處理null值,使用filter可以過濾掉;
- 不要濫用streams,因為我發現stream有時候會讓代碼變得更難以閱讀;
- 針對collections的迭代處理,可以多用stream處理;
- 要謹慎使用parallel streams,性能不一定比普通的loop要好;
- 最后,對外暴露api的入參檢查需要更全面;
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
參考資料
java se 8最佳實踐](https://www.jfokus.se/jfokus17/preso/java-se-8-best-practices.pdf)
流處理線:referencepipeline](http://download.java.net/lambda/b72/docs/api/java/util/stream/referencepipeline.html)
原文鏈接:http://duqicauc.gitee.io/2017/11/08/streams-tip-of-java8/