concat
concat方法將兩個Stream連接在一起,合成一個Stream。若兩個輸入的Stream都時排序的,則新Stream也是排序的;若輸入的Stream中任何一個是并行的,則新的Stream也是并行的;若關(guān)閉新的Stream時,原兩個輸入的Stream都將執(zhí)行關(guān)閉處理。
示例:
Stream.concat(Stream.of(1, 2, 3), Stream.of(4, 5))
.forEach(integer -> System.out.print(integer + " "));
// 打印結(jié)果
// 1 2 3 4 5
distinct
distinct方法以達(dá)到去除掉原Stream中重復(fù)的元素,生成的新Stream中沒有沒有重復(fù)的元素。
Stream.of(1,2,3,1,2,3)
.distinct()
.forEach(System.out::println); // 打印結(jié)果:1,2,3
創(chuàng)建了一個Stream(命名為A),其含有重復(fù)的1,2,3等六個元素,而實(shí)際上打印結(jié)果只有“1,2,3”等3個元素。因?yàn)锳經(jīng)過distinct去掉了重復(fù)的元素,生成了新的Stream(命名為B),而B
中只有“1,2,3”這三個元素,所以也就呈現(xiàn)了剛才所說的打印結(jié)果。
filter
filter方法對原Stream按照指定條件過濾,在新建的Stream中,只包含滿足條件的元素,將不滿足條件的元素過濾掉。
Stream.of(1, 2, 3, 4, 5)
.filter(item -> item > 3)
.forEach(System.out::println);// 打印結(jié)果:4,5
創(chuàng)建了一個含有1,2,3,4,5等5個整型元素的Stream,filter中設(shè)定的過濾條件為元素值大于3,否則將其過濾。而實(shí)際的結(jié)果為4,5。
==filter傳入的Lambda表達(dá)式必須是Predicate實(shí)例,參數(shù)可以為任意類型,而其返回值必須是boolean類型==。
map
map方法將對于Stream中包含的元素使用給定的轉(zhuǎn)換函數(shù)進(jìn)行轉(zhuǎn)換操作,新生成的Stream只包含轉(zhuǎn)換生成的元素。為了提高處理效率,官方已封裝好了,三種變形:mapToDouble,mapToInt,mapToLong。其實(shí)很好理解,如果想將原Stream中的數(shù)據(jù)類型,轉(zhuǎn)換為double,int或者是long是可以調(diào)用相對應(yīng)的方法。
示例:
Stream.of("a", "b", "hello")
.map(item-> item.toUpperCase())
.forEach(System.out::println);
// 打印結(jié)果
// A, B, HELLO
傳給map中Lambda表達(dá)式,接受了String類型的參數(shù),返回值也是String類型,在轉(zhuǎn)換行數(shù)中,將字母全部改為大寫
==map傳入的Lambda表達(dá)式必須是Function實(shí)例,參數(shù)可以為任意類型,而其返回值也是任性類型,javac會根據(jù)實(shí)際情景自行推斷。==
flatMap
flatMap方法與map方法類似,都是將原Stream中的每一個元素通過轉(zhuǎn)換函數(shù)轉(zhuǎn)換,不同的是,該換轉(zhuǎn)函數(shù)的對象是一個Stream,也不會再創(chuàng)建一個新的Stream,而是將原Stream的元素取代為轉(zhuǎn)換的Stream。如果轉(zhuǎn)換函數(shù)生產(chǎn)的Stream為null,應(yīng)由空Stream取代。flatMap有三個對于原始類型的變種方法,分別是:flatMapToInt,flatMapToLong和flatMapToDouble。
示例:
Stream.of(1, 2, 3)
.flatMap(integer -> Stream.of(integer * 10))
.forEach(System.out::println);
// 打印結(jié)果
// 10,20,30
傳給flatMap中的表達(dá)式接受了一個Integer類型的參數(shù),通過轉(zhuǎn)換函數(shù),將原元素乘以10后,生成一個只有該元素的流,該流取代原流中的元素。
==flatMap傳入的Lambda表達(dá)式必須是Function實(shí)例,參數(shù)可以為任意類型,而其返回值類型必須是一個Stream。==
sorted
sorted方法將對原Stream進(jìn)行排序,返回一個有序列的新Stream。sorterd有兩種變體sorted(),sorted(Comparator),前者將默認(rèn)使用Object.equals(Object)進(jìn)行排序,而后者接受一個自定義排序規(guī)則函數(shù)(Comparator),可按照意愿排序。
示例:
Stream.of(5, 4, 3, 2, 1)
.sorted()
.forEach(System.out::println;
// 打印結(jié)果
// 1,2,3,4,5
Stream.of(1, 2, 3, 4, 5)
.sorted(Comparator.reverseOrder())
.forEach(System.out::println;
// 打印結(jié)果
// 5, 4, 3, 2, 1
//list排序
list.stream().sorted(Comparator.comparing(Student::getAge))
Terminal(終點(diǎn)操作)
collect
Java 8系列之Stream的強(qiáng)大工具Collector
count
count方法將返回Stream中元素的個數(shù)。
示例:
long count = Stream.of(1, 2, 3, 4, 5)
.count();
System.out.println("count:" + count);// 打印結(jié)果:count:5
forEach
forEach方法前面已經(jīng)用了好多次,其用于遍歷Stream中的所元素,避免了使用for循環(huán),讓代碼更簡潔,邏輯更清晰。
示例:
Stream.of(5, 4, 3, 2, 1)
.sorted()
.forEach(System.out::println);
// 打印結(jié)果
// 1,2,3,4,5
max
max方法根據(jù)指定的Comparator,返回一個Optional,該Optional中的value值就是Stream中最大的元素。至于Optional是啥,后續(xù)再做介紹吧。
原Stream根據(jù)比較器Comparator,進(jìn)行排序(升序或者是降序),所謂的最大值就是從新進(jìn)行排序的,max就是取重新排序后的最后一個值,而min取排序后的第一個值。
示例:
Optional<Integer> max = Stream.of(1, 2, 3, 4, 5)
.max((o1, o2) -> o2 - o1);
System.out.println("max:" + max.get());// 打印結(jié)果:max:1
Optional<Integer> max = Stream.of(1, 2, 3, 4, 5)
.max(Comparator.comparingInt(o -> o));
System.out.println("max:" + max.get());// 打印結(jié)果:max:5
對于原Stream指定了Comparator,實(shí)際上是找出該Stream中的最小值,不過,在max方法中找最小值,更能體現(xiàn)出來Comparator的作用吧。max的值不言而喻,就是1了。
reduce
Short-circuiting(短路操作)
allMatch
allMatch操作用于判斷Stream中的元素是否全部滿足指定條件。如果全部滿足條件返回true,否則返回false。
示例:
boolean allMatch = Stream.of(1, 2, 3, 4)
.allMatch(integer -> integer > 0);
System.out.println("allMatch: " + allMatch); // 打印結(jié)果:allMatch: true
anyMatch
anyMatch操作用于判斷Stream中的是否有滿足指定條件的元素。如果最少有一個滿足條件返回true,否則返回false。
示例:
boolean anyMatch = Stream.of(1, 2, 3, 4)
.anyMatch(integer -> integer > 3);
System.out.println("anyMatch: " + anyMatch); // 打印結(jié)果:anyMatch: true
findAny
findAny操作用于獲取含有Stream中的某個元素的Optional,如果Stream為空,則返回一個空的Optional。由于此操作的行動是不確定的,其會自由的選擇Stream中的任何元素。在并行操作中,在同一個Stram中多次調(diào)用,可能會不同的結(jié)果。在串行調(diào)用時,Debug了幾次,發(fā)現(xiàn)每次都是獲取的第一個元素,個人感覺在串行調(diào)用時,應(yīng)該默認(rèn)的是獲取第一個元素。
示例:
Optional<Integer> any = Stream.of(1, 2, 3, 4).findAny();
limit
limit方法將截取原Stream,截取后Stream的最大長度不能超過指定值N。如果原Stream的元素個數(shù)大于N,將截取原Stream的前N個元素;如果原Stream的元素個數(shù)小于或等于N,將截取原Stream中的所有元素。
Stream.of(1, 2, 3,4,5)
.limit(2)
.forEach(System.out::println);
// 打印結(jié)果
// 1,2
傳入limit的值為2,也就是說被截取后的Stream的最大長度為2,又由于原Stream中有5個元素,所以將截取原Stream中的前2個元素,生成一個新的Stream。