原創(chuàng)文章,轉(zhuǎn)載請(qǐng)標(biāo)注出處:《Java基礎(chǔ)系列-Stream》
一、概述
Stream操作簡(jiǎn)稱流操作,這里的流與IO流毫無關(guān)系,這里的流指的是流式操作,就是流水線操作。
Stream流操作主要包包括三大模塊:創(chuàng)建流操作、中間流操作、終結(jié)流操作。
其中創(chuàng)建流主要是創(chuàng)建Stream對(duì)象。每個(gè)Stream對(duì)象只能使用一次終結(jié)操作。
中間流操作指的是各種中間流操作方法,比如去重、過濾、排序等
終結(jié)流操作指的結(jié)果操作,終結(jié)操作的目的是產(chǎn)生最終結(jié)果。
二、創(chuàng)建流
2.1 基于數(shù)組創(chuàng)建流
public class StreamTest {
public static void createStream() {
// 通過數(shù)組生成流
int[] ints = {1,2,3,4,5,6};
IntStream s1 = Arrays.stream(ints);
Stream s2 = Stream.of("111","222","333");
String[] ss = {"123","321","456","654"};
Stream<String> s3 = Arrays.stream(ss);
}
}
3.2 通過構(gòu)建器生成流
public class StreamTest {
public static void createStream() {
// 通過構(gòu)建器生成流
Stream<Object> s4 = Stream.builder().add("123").add("321").add("444").add("@21").build();
}
}
3.3 基于集合生成流
public class StreamTest {
public static void createStream() {
// 通過集合生成流
List<String> lists = Arrays.asList("123","321","1212","32321");
Stream<String> s5 = lists.stream();
Stream<String> s6 = lists.parallelStream();// 并行流
}
}
3.4 創(chuàng)建空流
public class StreamTest {
public static void createStream() {
// 創(chuàng)建空流
Stream<String> s7 = Stream.empty();
}
}
3.5 基于函數(shù)創(chuàng)建無限流
public class StreamTest {
public static void createStream() {
// 創(chuàng)建無限流
Stream.generate(()->"number"+new Random().nextInt()).limit(100).forEach(System.out::println);
Stream.iterate(0,n -> n+2).limit(10).forEach(System.out::println);
}
}
三、流中間操作
這里的流中間操作指的是該操作的返回值仍然是流。
| 序號(hào) | 操作 | 方法 | 說明 | 備注 |
|---|---|---|---|---|
| 1 | filter | Stream<T> filter(Predicate<? super T> predicate) | 返回當(dāng)前流中滿足參數(shù)predicate過濾條件的元素組成的新流 | 過濾器 |
| 2 | map | <R> Stream<R> map(Function<? super T, ? extends R> mapper) | 返回通過給定mapper作用于當(dāng)前流的每個(gè)元素之后的結(jié)果組成的新流 | 函數(shù) |
| 3 | mapToInt | IntStream mapToInt(ToIntFunction<? super T> mapper) | 返回通過給定mapper作用于當(dāng)前流的每個(gè)元素之后的結(jié)果組成的新的Int流 | 函數(shù) |
| 4 | mapToLong | LongStream mapToLong(ToLongFunction<? super T> mapper) | 返回通過給定mapper作用于當(dāng)前流的每個(gè)元素之后的結(jié)果組成的新的Long流 | 函數(shù) |
| 5 | mapToDouble | DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) | 返回通過給定mapper作用于當(dāng)前流的每個(gè)元素之后的結(jié)果組成的新的Double流 | 函數(shù) |
| 6 | flatMap | <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) | 根據(jù)給定的mapper作用于當(dāng)前流的每個(gè)元素,將結(jié)果組成新的流來返回 | 扁平函數(shù) |
| 7 | flatMapToInt | IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) | 根據(jù)給定的mapper作用于當(dāng)前流的每個(gè)元素,將結(jié)果組成新的Int流來返回 | 扁平函數(shù) |
| 8 | flatMapToLong | LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) | 根據(jù)給定的mapper作用于當(dāng)前流的每個(gè)元素,將結(jié)果組成新的Long流來返回 | 扁平函數(shù) |
| 9 | flatMapToDouble | DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) | 根據(jù)給定的mapper作用于當(dāng)前流的每個(gè)元素,將結(jié)果組成新的Double流來返回 | 扁平函數(shù) |
| 10 | distinct | Stream<T> distinct() | 返回去掉當(dāng)前流中重復(fù)元素之后的新流 | 去重 |
| 11 | sorted | Stream<T> sorted() | 返回當(dāng)前流中元素排序之后的新流,需要元素類型實(shí)現(xiàn)Comparable | 排序 |
| 12 | sorted | Stream<T> sorted(Comparator<? super T> comparator) | 返回當(dāng)前流中元素排序之后的新流,需要傳遞一個(gè)Comparator | 排序 |
| 13 | peek | Stream<T> peek(Consumer<? super T> action) | 針對(duì)流中的每個(gè)元素執(zhí)行操作action | 查閱 |
| 14 | limit | Stream<T> limit(long maxSize) | 返回指定的數(shù)量的元素組成的新流 | 限制 |
| 15 | skip | Stream<T> skip(long n) | 返回第n個(gè)之后的元素組成的新流 | 跳過 |
扁平函數(shù),就是將當(dāng)前流的每個(gè)元素通過執(zhí)行給定的mapper操作,從而擴(kuò)充,釋放每個(gè)元素內(nèi)的子元素,從而形成一個(gè)由所有子元素組成的新流,比如當(dāng)前流是包含N個(gè)字符串的流,使用這個(gè)方法,可以獲取到包含字符串中字符組成的流。
3.1 filter
filter方法是過濾器方法,針對(duì)的是流中所有元素,滿足條件的元素將會(huì)被保留以組成新的流。
public class StreamTest {
public static void filterTest(List<String> list){
list.stream()
.filter(e -> e.length() > 4 && e.length()<7)// 過濾掉長(zhǎng)度小于等于4,大于等于7的元素
.peek(System.out::println)// 查閱中間流結(jié)果
.collect(Collectors.toList());
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","asdaa","3e3e3e","2321eew","212121121");
filterTest(list);
}
}
執(zhí)行結(jié)果為:
asdaa
3e3e3e
filter方法的參數(shù)是Predicate類型,這個(gè)函數(shù)式接口用于獲取一個(gè)參數(shù)返回一個(gè)boolean值,整個(gè)參數(shù)作為過濾條件。
3.2 map
map方法可以理解為函數(shù),需要針對(duì)流中的每個(gè)元素執(zhí)行,然后將執(zhí)行的結(jié)果組成新的流返回。
public class StreamTest {
public static void mapTest(List<String> list){
list.stream()
.map(e -> "@" + e)// 為每個(gè)元素執(zhí)行操作:添加前綴
.peek(System.out::println)// 查閱中間流結(jié)果
.collect(Collectors.toList());
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","asdaa","3e3e3e","2321eew","212121121");
mapTest(list);
}
}
執(zhí)行結(jié)果為:
@123
@456
@789
@1101
@asdaa
@3e3e3e
@2321eew
@212121121
map方法的參數(shù)類型為Function,該函數(shù)式接口用于接受一個(gè)參數(shù),返回一個(gè)結(jié)果。
mapToInt、mapToLong、mapToDouble方法是map方法的擴(kuò)展,其參數(shù)分別為ToIntFunction、ToLongFunction、ToDoubleFunction,分別接口一個(gè)參數(shù),返回指定類型的值,分別為int、long、double,那么定義方法的時(shí)候就要注意返回值的類型了,必須一致,最后組成的新流就是一個(gè)int或long或double元素流(IntStream、LongStream、DoubleStream)。
mapToInt的簡(jiǎn)單使用(其他類似):
public class StreamTest {
public static void mapToIntTest(List<String> list){
list.stream()
.mapToInt(e -> e.length())// 以元素的長(zhǎng)度為新流
.peek(System.out::println)// 查詢中間結(jié)果
.toArray();
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","asdaa","3e3e3e","2321eew","212121121");
mapToIntTest(list);
}
}
執(zhí)行結(jié)果為:
3
3
3
4
5
6
7
9
3.3 flatMap
flatMap和map還是有點(diǎn)關(guān)系的,都是針對(duì)流中的每一個(gè)元素進(jìn)行操作,將結(jié)果組成新流,不過flatMap含有一層擴(kuò)展之意,就是當(dāng)流中元素包含子元素的時(shí)候,通過該方法,獲取到元素的子元素,并將子元素組成新流返回。
public class StreamTest {
public static void flatMap(List<String> list){
list.stream()
.filter(e -> e.length()>5 && e.length()<7)
.peek(System.out::println)
.map(e -> e.split(""))// 將每個(gè)字符串元素分解為字符數(shù)組
.flatMap(Arrays::stream)//將每個(gè)字符數(shù)組并轉(zhuǎn)化為流
.peek(System.out::println)
.collect(Collectors.toList());
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","asdaa","3e3e3e","2321eew","212121121");
flatMap(list);
}
}
執(zhí)行結(jié)果為:
3e3e3e
3
e
3
e
3
e
flatMapToInt、flatMapToLong、flatMapToDouble類似于之前的mapToInt之類。
3.4 distinct
distinct方法用于去重,很簡(jiǎn)單。
public class StreamTest {
public static void distinctTest(){
int[] int1 = {1,2,3,4};
int[] int2 = {5,3,7,1};
List<int[]> ints = Arrays.asList(int1,int2);
ints.stream()
.flatMapToInt(Arrays::stream)
.distinct()
.peek(System.out::println)
.toArray();
}
public static void main(String[] args) {
distinctTest();
}
}
執(zhí)行結(jié)果為:
1
2
3
4
5
7
結(jié)果中顯而易見,重復(fù)的1和3被去除了。
3.5 sorted
sorted表示對(duì)流中的元素進(jìn)行排序,需要使用Conparable和Comparator。
public class StreamTest {
public static void sortedTest(List<String> list){
System.out.println("----自然順序:");
list.stream().sorted().peek(System.out::println).collect(Collectors.toList());
System.out.println("----指定排序:");
list.stream().sorted((a,b) -> a.length()-b.length()).peek(System.out::println).collect(Collectors.toList());
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","asdaa","3e3e3e","2321eew","212121121");
sortedTest(list);
}
}
執(zhí)行結(jié)果為:
----自然順序:
1101
123
212121121
2321eew
3e3e3e
456
789
asdaa
----指定排序:
123
456
789
1101
asdaa
3e3e3e
2321eew
212121121
當(dāng)調(diào)用無參的sorted方法時(shí),采用自然排序法排序,當(dāng)使用指定比較器的方式時(shí),可以自由指定排序規(guī)則。
3.6 limit
limit可用于從首個(gè)元素開始截取N個(gè)元素,組成新流返回。
public class StreamTest {
public static void limitTest(List<String> list){
list.stream().limit(2).peek(System.out::println).collect(Collectors.toList());
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","asdaa","3e3e3e","2321eew","212121121");
limitTest(list);
}
}
執(zhí)行結(jié)果為:
123
456
3.7 skip
skip表示放棄N個(gè)元素,將剩余元素組成新流返回。
public class StreamTest {
public static void skipTest(List<String> list){
list.stream().skip(2).peek(System.out::println).collect(Collectors.toList());
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","asdaa","3e3e3e","2321eew","212121121");
skipTest(list);
}
}
執(zhí)行結(jié)果為:
789
1101
asdaa
3e3e3e
2321eew
212121121
放棄了前2個(gè)元素,將剩余元素組成了新流。
四、流終結(jié)操作
| 序號(hào) | 操作 | 方法 | 說明 | 備注 |
|---|---|---|---|---|
| 1 | forEach | void forEach(Consumer<? super T> action) | 對(duì)流中的每個(gè)元素執(zhí)行指定的操作action | 遍歷 |
| 2 | forEachOrdered | void forEachOrdered(Consumer<? super T> action) | 如果有序,則按序遍歷流中元素,針對(duì)每個(gè)元素執(zhí)行指定操作 | 按序遍歷 |
| 3 | toArray | Object[] toArray() | 返回一個(gè)包含流中所有元素的數(shù)組 | 數(shù)組化 |
| 4 | toArray | <A> A[] toArray(IntFunction<A[]> generator) | 返回一個(gè)包含流中所有元素的參數(shù)指定類型的數(shù)組 | 數(shù)組化 |
| 5 | reduce | T reduce(T identity, BinaryOperator<T> accumulator) | 以給定初始值為基礎(chǔ)歸納流中元素,返回一個(gè)值 | 歸納 |
| 6 | reduce | Optional<T> reduce(BinaryOperator<T> accumulator) | 直接歸納流中的元素,返回一個(gè)封裝有結(jié)果的Optional | 歸納 |
| 7 | reduce | <U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner) | 以給定的初始值為基礎(chǔ),(并行)歸納流中元素,最后將各個(gè)線程的結(jié)果再統(tǒng)一歸納,返回一個(gè)值 | 歸納 |
| 8 | collect | <R, A> R collect(Collector<? super T, A, R> collector) | 根據(jù)給定的收集器收集元素 | 歸納 |
| 9 | collect | <R> R collect(Supplier<R> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner) | 根據(jù)給定的各個(gè)參數(shù)歸納元素 | 歸納 |
| 10 | max | Optional<T> max(Comparator<? super T> comparator) | 根據(jù)給定的比較器,返回流中最大元素的Optional表示 | 最大值 |
| 11 | min | Optional<T> min(Comparator<? super T> comparator) | 根據(jù)給定的比較器,返回流中最小元素的Optional表示 | 最小值 |
| 12 | count | long count() | 返回流中元素的個(gè)數(shù) | 計(jì)數(shù) |
| 13 | anyMatch | boolean anyMatch(Predicate<? super T> predicate) | 校驗(yàn)流中是否有滿足給定條件的元素 | 校驗(yàn) |
| 14 | allMatch | boolean allMatch(Predicate<? super T> predicate) | 校驗(yàn)流中的元素是否全部滿足給定條件 | 校驗(yàn) |
| 15 | noneMatch | boolean noneMatch(Predicate<? super T> predicate) | 校驗(yàn)流中的元素是否全不滿足給點(diǎn)條件 | 校驗(yàn) |
| 16 | findFirst | Optional<T> findFirst() | 返回首個(gè)元素的Optional表示,如果為空流,返回空的Optional | 返回首個(gè)元素 |
| 17 | findAny | Optional<T> findAny() | 如果流中有元素,則返回第一個(gè)元素的Optional表示,否則返回一個(gè)空的Optional | 校驗(yàn)是否為空流 |
4.1 forEach和forEachOrdered
forEach就是遍歷操作,針對(duì)流中的每個(gè)元素做最后的操作。
public class StreamTest {
public static void forEachTest(List<String> list){
list.stream().parallel().forEach(System.out::println);
}
public static void forEachOrderedTest(List<String> list){
list.stream().parallel().forEachOrdered(System.out::println);
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
forEachTest(list);
System.out.println("----------");
forEachOrderedTest(list);
}
}
執(zhí)行結(jié)果為:
asdaa
212121121
789
1101
2321eew
3e3e3e
456
123
----------
123
456
789
1101
212121121
asdaa
3e3e3e
2321eew
二者都是遍歷操作,從結(jié)果是可以看出來,如果是單線程(也就是不加parallel方法的情況)那么二者結(jié)果是一致的,但是如果采用并行遍歷,那么就有區(qū)別了,forEach并行遍歷不保證順序(順序隨機(jī)),forEachOrdered卻是保證順序來進(jìn)行遍歷的。
4.2 toArray
public class StreamTest {
public static void toArrayTest(List<String> list){
Object[] objs = list.stream().filter(e -> e.length()>6).toArray();
String[] ss = list.stream().filter(e -> e.length()>6).toArray(String[]::new);
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
toArrayTest(list);
}
}
toArray有兩個(gè)方法,一個(gè)是無參方法,一個(gè)有參方法。
無參方法返回的只能是Object[]數(shù)組類型,而有參方法,可以指定結(jié)果數(shù)組類型,此乃二者區(qū)別。
使用有參方法可以直接完成類型轉(zhuǎn)換,一次到位。
4.4 reduce
reduce方法有三個(gè)重載的方法,
public interface Stream<T> extends BaseStream<T, Stream<T>> {
Optional<T> reduce(BinaryOperator<T> accumulator);// 編號(hào)1
T reduce(T identity, BinaryOperator<T> accumulator);// 編號(hào)2
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);// 編號(hào)3
}
這三個(gè)方法的作用其實(shí)是一樣的,就是歸納總結(jié)的意思。
首先看編號(hào)1方法,只有一個(gè)參數(shù)accumulator,這是一個(gè)累加器,方法的作用就是將這個(gè)累加器作用到流中的每一個(gè)元素,他需要兩個(gè)輸入?yún)?shù),有一個(gè)輸出參數(shù),意思是對(duì)兩個(gè)元素執(zhí)行某些操作,返回一個(gè)結(jié)果,然后將這個(gè)結(jié)果與下一個(gè)元素作為參數(shù)再輸入該方法,執(zhí)行操作后再返回一個(gè)新結(jié)果,以此類推,直到最后一個(gè)元素執(zhí)行完畢,返回的就是最終結(jié)果,因?yàn)榱髦械脑匚覀兪遣淮_定的,那么我們就無法確定reduce的結(jié)果,因?yàn)槿绻鳛榭?,那么將?huì)返回null,所以使用Optional作為返回值,妥善處理null值。
再看編號(hào)2方法,在編號(hào)1方法的基礎(chǔ)上加了一個(gè)identity,且不再使用Optional,為什么呢,因?yàn)樾录拥膇dentity其實(shí)是個(gè)初始值,后續(xù)的操作都在這個(gè)值基礎(chǔ)上執(zhí)行,那么也就是說,,如果流中沒有元素的話,還有初始值作為結(jié)果返回,不會(huì)存在null的情況,也就不用Optional了。
再看編號(hào)3方法,在編號(hào)2方法的基礎(chǔ)上又加了一個(gè)參數(shù)combiner,其實(shí)這個(gè)方法是用于處理并行流的歸納操作,最后的參數(shù)combiner用于歸納各個(gè)并行的結(jié)果,用于得出最終結(jié)果。
那么如果不使用并行流,一般使用編號(hào)2方法就足夠了。
示例:
public class StreamTest {
public static void reduceTest(){
List<Integer> ints = Arrays.asList(1,2,3,4,5,6,7,8,9);
Optional<Integer> optional = ints.stream().reduce(Integer::sum);
System.out.println(optional.get());
System.out.println("-------------");
Integer max = ints.stream().reduce(Integer.MIN_VALUE, Integer::max);
System.out.println(max);
System.out.println("-------------");
Integer min = ints.parallelStream().reduce(Integer.MAX_VALUE, Integer::min, Integer::min);
System.out.println(min);
}
public static void main(String[] args) {
reduceTest();
}
}
執(zhí)行結(jié)果為:
45
-------------
9
-------------
1
4.5 collect
collect操作是Stream中最強(qiáng)大的方法了,幾乎可以得到任何你想要的結(jié)果,collect方法有兩個(gè)重載方法:
public interface Stream<T> extends BaseStream<T, Stream<T>> {
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);// 編號(hào)1
<R, A> R collect(Collector<? super T, A, R> collector);// 編號(hào)2
}
collect是收集的意思,這里的作用就是收集歸納,將流中的數(shù)據(jù)映射為各種結(jié)果。
首先看看編號(hào)1方法,有三個(gè)參數(shù):supplier用于生成一個(gè)R類型的結(jié)果容器來盛放結(jié)果,accumulator累加器用于定義盛放的方式,其中T為一個(gè)元素,R為結(jié)果容器,第三個(gè)參數(shù)combiner的作用是將并行操作的各個(gè)結(jié)果整合起來。
public class StreamTest {
public static void collectTest1(List<String> list){
ArrayList<String> arrayList = list.stream().skip(4).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
arrayList.forEach(System.out::println);
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
collectTest1(list);
}
}
執(zhí)行結(jié)果:
212121121
asdaa
3e3e3e
2321eew
例子中,第一個(gè):ArrayList::new表示創(chuàng)建一個(gè)新的ArrayList集合,第二個(gè) ArrayList::add表示將元素一個(gè)一個(gè)添加到之前的集合中,第三個(gè)ArrayList::addAll表示將多個(gè)線程的ArrayList集合一個(gè)一個(gè)的整體添加到第一個(gè)集合中,最終整合出一個(gè)最終結(jié)果并返回。
然后我們重點(diǎn)來看看編號(hào)2方法。
它只需要一個(gè)Collector類型的參數(shù),這個(gè)Collector可以稱呼為收集器,我們可以隨意組裝一個(gè)收集器來進(jìn)行元素歸納。
Collector是定義來承載一個(gè)收集器,但是JDK提供了一個(gè)Collectors工具類,在這個(gè)工具類里面預(yù)實(shí)現(xiàn)了N多的Collector供我們直接使用,之前的Collectors.toList()就是其用法之一。具體見下文。
public class StreamTest {
public static void collectTest2(List<String> list){
Set<String> set = list.stream().skip(4).collect(Collectors.toSet());
set.forEach(System.out::println);
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
collectTest2(list);
}
}
執(zhí)行結(jié)果為:
212121121
2321eew
3e3e3e
asdaa
有關(guān)Collector具體可閱讀:Java流式操作系列-Collector和Collectors
4.6 max\min
通過給定的比較器,得出流中最大\最小的元素,為避免null返回,這里使用Optional來封裝返回值。
public class StreamTest {
public static void maxMinTest(List<String> list){
System.out.println("長(zhǎng)度最大:" + list.stream().max((a,b)-> a.length()-b.length()));
System.out.println("長(zhǎng)度最小:" + list.stream().min((a,b)-> a.length()-b.length()));
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
maxMinTest(list);
}
}
執(zhí)行結(jié)果為:
長(zhǎng)度最大:Optional[212121121]
長(zhǎng)度最?。篛ptional[123]
4.7 count
count是無參方法,用于計(jì)數(shù),返回流中元素個(gè)數(shù)。
public class StreamTest {
public static void countTest(List<String> list){
System.out.println("元素個(gè)數(shù)為:" + list.stream().count());
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
countTest(list);
}
}
執(zhí)行結(jié)果為:
元素個(gè)數(shù)為:8
4.8 anyMatch
該方法需要一個(gè)Predicate參數(shù),用于校驗(yàn)流中的元素,只要有一個(gè)滿足規(guī)則,則返回true,全不滿足,返回false。
public class StreamTest {
public static void anyMatchTest(List<String> list){
System.out.println(list.stream().anyMatch(e -> e.length()>10));
System.out.println(list.stream().anyMatch(e -> e.length()>8));
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
anyMatchTest(list);
}
}
執(zhí)行結(jié)果為:
false
true
4.9 allMatch
該方法同樣需要一個(gè)Predicate參數(shù),用于校驗(yàn)流中的所有元素,只有全部滿足規(guī)則才能返回true,只要有一個(gè)不滿足則返回false。
public class StreamTest {
public static void allMatchTest(List<String> list){
System.out.println(list.stream().allMatch(e -> e.length()>1));
System.out.println(list.stream().allMatch(e -> e.length()>3));
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
allMatchTest(list);
}
}
執(zhí)行結(jié)果為:
true
false
4.10 noneMatch
該方法同樣需要一個(gè)Predicate參數(shù),用于校驗(yàn)流中的所有元素,只有所有元素都不滿足規(guī)則的情況下返回true,否則返回false。
public class StreamTest {
public static void noneMatchTest(List<String> list){
System.out.println(list.stream().noneMatch(e -> e.length()>10));
System.out.println(list.stream().noneMatch(e -> e.length()>8));
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
noneMatchTest(list);
}
}
執(zhí)行結(jié)果為:
true
false
4.11 findFirst
該方法無參數(shù),主要用于獲取流中的第一個(gè)元素,如果流無序,那么可能返回任意一個(gè)。
public class StreamTest {
public static void findFirstTest(List<String> list){
System.out.println(list.stream().parallel().findFirst().get());
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
findFirstTest(list);
}
}
執(zhí)行結(jié)果為:
123
4.12 findAny
該方法無參數(shù),主要用于獲取流中的任一元素。
public class StreamTest {
public static void findAnyTest(List<String> list){
System.out.println(list.stream().parallel().findAny().get());
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
findAnyTest(list);
}
}
執(zhí)行結(jié)果為:
asdaa
五、總結(jié)
流式操作代碼描述性強(qiáng),易理解,而且功能強(qiáng)大,可以簡(jiǎn)化很多集合操作。在我們需要對(duì)集合數(shù)據(jù)進(jìn)行處理的時(shí)候,不妨試試使用流式操作來實(shí)現(xiàn)。
參考: