Java8中Stream使用的一個(gè)注意事項(xiàng)
Stream簡(jiǎn)介
我們先來看看Java里面是怎么定義Stream的:
A sequence of elements supporting sequential and parallel aggregate operations.
我們來解讀一下上面的那句話:
- Stream是元素的集合,這點(diǎn)讓Stream看起來用些類似Iterator;
- 可以支持順序和并行的對(duì)原Stream進(jìn)行匯聚的操作;
大家可以把Stream當(dāng)成一個(gè)高級(jí)版本的Iterator。原始版本的Iterator,用戶只能一個(gè)一個(gè)的遍歷元素并對(duì)其執(zhí)行某些操作;高級(jí)版本的Stream,用戶只要給出需要對(duì)其包含的元素執(zhí)行什么操作,比如“過濾掉長(zhǎng)度大于10的字符串”、“獲取每個(gè)字符串的首字母”等,具體這些操作如何應(yīng)用到每個(gè)元素上,就給Stream就好了?。ㄟ@個(gè)秘籍,一般人我不告訴他:))大家看完這些可能對(duì)Stream還沒有一個(gè)直觀的認(rèn)識(shí),莫急,咱們來段代碼。
//Lists是Guava中的一個(gè)工具類 List<Integer> nums = Lists.newArrayList(1,null,3,4,null,6); nums.stream().filter(num -> num != null).count();
上面這段代碼是獲取一個(gè)List中,元素不為null的個(gè)數(shù)。這段代碼雖然很簡(jiǎn)短,但是卻是一個(gè)很好的入門級(jí)別的例子來體現(xiàn)如何使用Stream,正所謂“麻雀雖小五臟俱全”。
引子
今天下午遇到一個(gè)NPE,如下圖所示

跟了下源碼,最后跟到ReferencePipeline#193行,應(yīng)該是調(diào)用apply的時(shí)候,入?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));
}
};
}
};
}
為了驗(yàn)證我的想法,我寫了如下的測(cè)試?yán)樱?/p>
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;
}
最佳實(shí)踐
- 在Streams開始和結(jié)束之前,都需要避免處理null值,使用filter可以過濾掉;
- 不要濫用Streams,因?yàn)槲野l(fā)現(xiàn)Stream有時(shí)候會(huì)讓代碼變得更難以閱讀;
- 針對(duì)Collections的迭代處理,可以多用Stream處理;
- 要謹(jǐn)慎使用Parallel Streams,性能不一定比普通的loop要好;
- 最后,對(duì)外暴露API的入?yún)z查需要更全面;
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
參考資料
Java SE 8最佳實(shí)踐](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)文章
SpringBoot整合MyBatis和MyBatis-Plus請(qǐng)求后不打印sql日志的問題解決
本文主要介紹了SpringBoot整合MyBatis和MyBatis-Plus請(qǐng)求后不打印sql日志的問題解決文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07
SpringCloud使用FFmpeg對(duì)視頻壓縮處理的代碼示例
在現(xiàn)代的視頻處理系統(tǒng)中,壓縮視頻以減小存儲(chǔ)空間、加快傳輸速度是一項(xiàng)非常重要的任務(wù),FFmpeg作為一個(gè)強(qiáng)大的開源工具,廣泛應(yīng)用于音視頻的處理,包括視頻的壓縮和格式轉(zhuǎn)換等,本文將通過Java代碼示例,向您展示如何使用FFmpeg進(jìn)行視頻壓縮,并介紹相關(guān)參數(shù)的設(shè)置2024-11-11
SpringBoot使用阿里oss實(shí)現(xiàn)文件上傳的流程步驟
云服務(wù)指的就是通過互聯(lián)網(wǎng)對(duì)外提供的各種各樣的服務(wù),比如像:語音服務(wù)、短信服務(wù)、郵件服務(wù)、視頻直播服務(wù)、文字識(shí)別服務(wù)、對(duì)象存儲(chǔ)服務(wù)等等,本文通過代碼示例和圖文給大家介紹了SpringBoot使用阿里oss實(shí)現(xiàn)文件上傳的流程步驟,需要的朋友可以參考下2025-01-01

