Java基礎(chǔ)系列-Stream


原創(chuàng)文章腔长,轉(zhuǎn)載請(qǐng)標(biāo)注出處:《Java基礎(chǔ)系列-Stream》


一袭祟、概述

Stream操作簡稱流操作,這里的流與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)// 過濾掉長度小于等于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的簡單使用(其他類似):

public class StreamTest {
    public static void mapToIntTest(List<String> list){
        list.stream()
                .mapToInt(e -> e.length())// 以元素的長度為新流
                .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方法用于去重玻孟,很簡單笆载。

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("長度最大:" + list.stream().max((a,b)-> a.length()-b.length()));
        System.out.println("長度最写兴:" + 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é)果為:

長度最大:Optional[212121121]
長度最小:Optional[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)大港庄,可以簡化很多集合操作倔既。在我們需要對(duì)集合數(shù)據(jù)進(jìn)行處理的時(shí)候,不妨試試使用流式操作來實(shí)現(xiàn)攘轩。

參考:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末叉存,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子度帮,更是在濱河造成了極大的恐慌歼捏,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笨篷,死亡現(xiàn)場(chǎng)離奇詭異瞳秽,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)率翅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門练俐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人冕臭,你說我怎么就攤上這事腺晾⊙嘧叮” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵悯蝉,是天一觀的道長归形。 經(jīng)常有香客問我,道長鼻由,這世上最難降的妖魔是什么暇榴? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮蕉世,結(jié)果婚禮上蔼紧,老公的妹妹穿的比我還像新娘。我一直安慰自己狠轻,他們只是感情好奸例,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著哈误,像睡著了一般哩至。 火紅的嫁衣襯著肌膚如雪躏嚎。 梳的紋絲不亂的頭發(fā)上蜜自,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音卢佣,去河邊找鬼重荠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛虚茶,可吹牛的內(nèi)容都是我干的戈鲁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嘹叫,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼婆殿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起罩扇,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤婆芦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后喂饥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體消约,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年员帮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了或粮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡捞高,死狀恐怖氯材,靈堂內(nèi)的尸體忽然破棺而出渣锦,到底是詐尸還是另有隱情,我是刑警寧澤氢哮,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布泡挺,位于F島的核電站,受9級(jí)特大地震影響命浴,放射性物質(zhì)發(fā)生泄漏娄猫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一生闲、第九天 我趴在偏房一處隱蔽的房頂上張望媳溺。 院中可真熱鬧,春花似錦碍讯、人聲如沸悬蔽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蝎困。三九已至,卻和暖如春倍啥,著一層夾襖步出監(jiān)牢的瞬間禾乘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國打工虽缕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留始藕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓氮趋,卻偏偏與公主長得像伍派,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子剩胁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353