Java8中Stream使用的一個注意事項
Stream簡介
我們先來看看Java里面是怎么定義Stream的:
A sequence of elements supporting sequential and parallel aggregate operations.
我們來解讀一下上面的那句話:
- Stream是元素的集合,這點讓Stream看起來用些類似Iterator;
- 可以支持順序和并行的對原Stream進行匯聚的操作;
大家可以把Stream當成一個高級版本的Iterator。原始版本的Iterator,用戶只能一個一個的遍歷元素并對其執(zhí)行某些操作;高級版本的Stream,用戶只要給出需要對其包含的元素執(zhí)行什么操作,比如“過濾掉長度大于10的字符串”、“獲取每個字符串的首字母”等,具體這些操作如何應用到每個元素上,就給Stream就好了!(這個秘籍,一般人我不告訴他:))大家看完這些可能對Stream還沒有一個直觀的認識,莫急,咱們來段代碼。
//Lists是Guava中的一個工具類 List<Integer> nums = Lists.newArrayList(1,null,3,4,null,6); nums.stream().filter(num -> num != null).count();
上面這段代碼是獲取一個List中,元素不為null的個數(shù)。這段代碼雖然很簡短,但是卻是一個很好的入門級別的例子來體現(xiàn)如何使用Stream,正所謂“麻雀雖小五臟俱全”。
引子
今天下午遇到一個NPE,如下圖所示
跟了下源碼,最后跟到ReferencePipeline#193行,應該是調(diào)用apply的時候,入?yún)為null,從而觸發(fā)了空指針異常。
@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)); } }; } }; }
為了驗證我的想法,我寫了如下的測試例子:
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開始和結(jié)束之前,都需要避免處理null值,使用filter可以過濾掉;
- 不要濫用Streams,因為我發(fā)現(xiàn)Stream有時候會讓代碼變得更難以閱讀;
- 針對Collections的迭代處理,可以多用Stream處理;
- 要謹慎使用Parallel Streams,性能不一定比普通的loop要好;
- 最后,對外暴露API的入?yún)z查需要更全面;
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
參考資料
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)
相關(guān)文章
java調(diào)用python腳本引入第三方庫失敗的實現(xiàn)
本文主要介紹了java調(diào)用python腳本引入第三方庫失敗的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-07-07Java線程池隊列LinkedTransferQueue示例詳解
這篇文章主要為大家介紹了Java線程池隊列LinkedTransferQueue示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12Java 遞歸查詢部門樹形結(jié)構(gòu)數(shù)據(jù)的實踐
本文主要介紹了Java 遞歸查詢部門樹形結(jié)構(gòu)數(shù)據(jù)的實踐,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09Java 根據(jù)網(wǎng)址查詢DNS/IP地址的方法
這篇文章主要介紹了Java 根據(jù)網(wǎng)址查詢DNS/IP地址的方法,具體實現(xiàn)代碼,大家參考下本文2017-12-12gateway、webflux、reactor-netty請求日志輸出方式
這篇文章主要介紹了gateway、webflux、reactor-netty請求日志輸出方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03