溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

jdk8中stream的函數(shù)和特性

發(fā)布時(shí)間:2020-06-06 14:51:44 來源:億速云 閱讀:520 作者:Leah 欄目:編程語言

本文以jdk8中stream為例,為大家分析stream的函數(shù)以及函數(shù)的使用方法,并介紹了stream的特性。閱讀完整文相信大家對(duì)jdk8中的stream有了一定的認(rèn)識(shí)。

篩選/過濾(filter)

日常中對(duì)于數(shù)據(jù)的篩選是非常普通的操作了,以前通常都會(huì)放在數(shù)據(jù)庫篩選或者自己寫方法進(jìn)行篩選。
獲取某些行數(shù)據(jù),一行就搞定。

List<SysUser> users = mapper.getAllUsers();
// 獲取指定id的用戶
List<SysUser> targetUsers = users.stream().filter(u->ids.contains(u.getId())).collect(Collectors.toList());

// .collect(Collectors.toList()):可以根據(jù)需要換成其他集合

屬性處理(map)

該操作的作用就是將input Stream的每一個(gè)元素,按照一定規(guī)則處理之后,映射成output Stream的另一個(gè)元素,相當(dāng)于一對(duì)一的輸入輸出,平時(shí)該方式使用較多。

比如說:

List<SysUser> users = mapper.getAllUsers();
// 把名字轉(zhuǎn)換成大寫;
List<SysUser> targetUsers = users.stream().map(u->u.getName().toUpperCase()).collect(Collectors.toList());

mapToInt/mapToLong/mapToDouble方法

顧名思義,用于轉(zhuǎn)換流類型的方法。這個(gè)沒有什么可說的。

flatMap方法

這個(gè)操作方法被稱作:平鋪,我理解的更像是集合的合并操作??聪旅娴睦印?/p>

Stream<List<Integer>> inputStream = Stream.of(
        Arrays.asList(1),
        Arrays.asList(2, 3),
        Arrays.asList(4, 5, 6)
);
Stream<Integer> outputStream = inputStream.flatMap((childList) -> childList.stream());
List<Integer> list = outputStream.collect(Collectors.toList());
System.out.println(list);
// [1,2,3,4,5,6]

將二維轉(zhuǎn)成了一維。

foreach遍歷

比較簡(jiǎn)單,可能需要注意的是,不能修改自己包含的本地變量值,也不能使用 break/return 之類的關(guān)鍵字提前結(jié)束循環(huán)。

findFirst方法

獲取第一個(gè)元素。但沒有獲取第二個(gè)、第三個(gè)、最后一個(gè)元素的函數(shù)方法。

reduce方法

這個(gè)方法的作用主要是把Stream中的元素組合起來,比如說字符串拼接,數(shù)值類型的求和等都是特殊的reduce操作,并且我們可以根據(jù)重載方法選擇是否有初始值。

// 字符串連接,concat = "ABCD"
String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat);
// 求最小值,minValue = -3.0
double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);
// 求和,sumValue = 10, 有起始值
int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);
// 求和的另一種形式
int sum = Stream.of(1, 2, 3, 4).reduce(0, (a,b) -> a+b);
// 求和,sumValue = 10, 無起始值
sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
// 過濾,字符串連接,concat = "ace"
concat = Stream.of("a", "B", "c", "D", "e", "F")
        .filter(x -> x.compareTo("Z") > 0)
        .reduce("", String::concat);

reduce方法可以結(jié)合filter,map進(jìn)行各種復(fù)合操作,是我們非常常用的方法。也是我們需要掌握和理解的方法。

limit/skip方法

limit是取流前n個(gè)元素,skip是跳過前m個(gè)元素剩余的元素,這兩個(gè)方法有點(diǎn)像用來做分頁用的。在mongodb操作內(nèi)存數(shù)據(jù)時(shí)經(jīng)常會(huì)使用到這些方法。

sorted方法

進(jìn)行排序,默認(rèn)的自然排序規(guī)則進(jìn)行排序, 也可以指定具體的比較器來進(jìn)行排序。

List<Integer> list = Arrays.asList(5, 7, 1, 4, 2, 6, 3, 8, 9, 10);
list.stream().limit(5).sorted().forEach(System.out::print);
System.out.println();
list.stream().limit(5).sorted(Comparator.reverseOrder()).forEach(System.out::print);

min/max/distinct方法

Stream中的findAny、max/min、reduce等方法等返回Optional值。還有例如IntStream.average()返回OptionalDouble等等.這里比較重點(diǎn)的是Optional的返回值類型,Optional:這也是一個(gè)模仿 Scala 語言中的概念,作為一個(gè)容器,它可能含有某值,或者不包含,使用它的目的是盡可能避免NullPointerException。

// Optional 的兩個(gè)用例

 // Java 8
 Optional.ofNullable(message).ifPresent(System.out::println);

 // Pre-Java 8
 if (message != null) {
 System.out.println(message);
 }

 // Java 8
return Optional.ofNullable(message).map(String::length).orElse(-1);

// Pre-Java 8
return if (message != null) ? message.length() : -1;
 };

使用Optional代碼的可讀性更好,而且它提供的是編譯時(shí)檢查,能極大的降低NPE這種Runtime Exception 對(duì)程序的影響,或者迫使程序員更早的在編碼階段處理空值問題,而不是留到運(yùn)行時(shí)再發(fā)現(xiàn)和調(diào)試。

小結(jié)

Stream 的特性可以歸納為:

1.不是數(shù)據(jù)結(jié)構(gòu);
2.它不做內(nèi)部存儲(chǔ),它只是用操作管道從source(數(shù)據(jù)結(jié)構(gòu)、數(shù)組、generator function、IO channel)抓取數(shù)據(jù);
3.它也絕不修改自己所封裝的底層數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù)。例如Stream的filter操作會(huì)產(chǎn)生一個(gè)不包含被過濾元素的新Stream,而不是從source刪除那些元素;
4.所有Stream的操作必須以lambda表達(dá)式為參數(shù);不支持索引訪問;
5.你可以請(qǐng)求第一個(gè)元素,但無法請(qǐng)求第二個(gè),第三個(gè),或最后一個(gè);
6.惰性化:到具體使用才會(huì)進(jìn)行操作;很多Stream操作是向后延遲的,一直到它弄清楚了最后需要多少數(shù)據(jù)才會(huì)開始;
7.Intermediate操作永遠(yuǎn)是惰性化的;
8.當(dāng)一個(gè) Stream 是并行化的,就不需要再寫多線程代碼,所有對(duì)它的操作會(huì)自動(dòng)并行進(jìn)行的;
9.可以是無限的。集合有固定大小,Stream 則不必。limit(n)和findFirst()這類的short-circuiting操作可以對(duì)無限的Stream進(jìn)行運(yùn)算并很快完成。

以上就是jdk8中stream的函數(shù)和特性的詳細(xì)內(nèi)容了,看完之后是否有所收獲呢?小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ骺赡軙?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI