Stream 的使用

一逗鸣、什么是 Stream?

  1. Stream 是 Java8 中處理集合的關(guān)鍵抽象概念帘饶,它可以指定你希望對集合進行的操作,可以執(zhí)行非常復雜的查找群扶、過濾和映射數(shù)據(jù)等操作及刻。

  2. 使用 Stream API 對集合數(shù)據(jù)進行操作,就類似于使用 SQL 執(zhí)行的數(shù)據(jù)庫查詢竞阐。也可以使用 Stream API 來并行執(zhí)行操作缴饭。簡而言之,Stream API 提供了一種高效且易于使用的處理數(shù)據(jù)的方式骆莹。

二颗搂、Stream 的特點

  1. stream 自己不會保存數(shù)據(jù)。
  2. 不會改變數(shù)據(jù)源幕垦,相反丢氢,他們會返回一個持有結(jié)構(gòu)的新的 Stream。
  3. Stream 操作是延遲執(zhí)行的先改,因此疚察,它會等到需要結(jié)果時才執(zhí)行。

三仇奶、Stream 的三個操作步驟

  1. 產(chǎn)生 Stream
    ① 通過 Collections 系列集合提供的 stream()方法或 parallelStream()獲取
    ② 通過 Arrays 中的靜態(tài)方法獲取
    ③ 通過 Stream 類中的靜態(tài)方法 of()獲取
    ④ 創(chuàng)建無限流
    ⑤ ...

  2. 中間操作
    (1)篩選與切片:
    ??① Stream<T> filter(Predicate predicate); // 過濾(返回值 boolean)
    ??② Stream<T> limit(long maxSize); // 限制
    ??③ Stream<T> skip(long n); // 跳過
    ??④ Stream<T> distinct(); // 去重(比較 hash 值)
    (2)映射
    ??① Stream<R> map(Function mapper); // 參數(shù) lambda 表達式(有返回值)
    ??② Stream<R> flatMap(Function mapper); // 參數(shù) lambda 表達式(有返回值)
    (3)排序
    ??① Stream<T> sorted() // 自然排序 Comparable
    ??② Stream<T> sorted(Comparator comparator); // 定制排序
    (4)消費(與 map() 相似)
    ??① Stream<T> peek(Consumer action); // 參數(shù) lambda 表達式(無返回值)

  3. 終止操作(終端操作)
    (1)查找與匹配
    ??allMatch:檢查是否匹配所有元素
    ??noneMatch:檢查是否沒匹配所有元素
    ??anyMatch:檢查是否至少有一個元素匹配
    ??findFirst:返回流中第一個元素
    ??findAny:返回流中的任意元素
    ??count:返回流中元素的總個數(shù)
    ??max:返回流中元素最大值
    ??min:返回流中元素最小值
    (2)歸約與收集
    ??① Optional<T> reduce(BinaryOperator<T> accumulator)
    ??② R collect(Collector collector);

四貌嫡、Stream 演示

以下為全部代碼,可直接運行
Person.java

package com.wl.model;

/**
 * @author  WL
 * @date : 2021年6月3日 08:27:19
 */
public class Person implements Comparable<Person> {
    private String name;
    private Integer age;
    private String gender;

    public Person() {
    }

    public Person(String name, Integer age, String gender) {
        super();
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", gender=" + gender + "]";
    }

    @Override
    public int compareTo(Person person) {
        return person.getAge() - this.age;
    }
}

StreamDemo.java

package com.wl.stream;

import com.wl.model.Person;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author  WL
 * @date : 2021年6月3日 08:27:19
 */
public class StreamDemo {
    public static Person person1 = new Person("Tom", 20, "男");
    public static Person person2 = new Person("Scott", 21, "女");
    public static Person person3 = new Person("John", 22, "男");
    public static Person person4 = new Person("Bob", 23, "女");

    public static List<Person> list = Arrays.asList(person1, person2, person3, person4, person4);

    public static void main(String[] args) {

        System.out.println("請輸入要要演示的方法序號:");
        System.out.println("1.創(chuàng)建 Stream");
        System.out.println("2.中間操作--篩選與切片");
        System.out.println("3.中間操作--映射");
        System.out.println("4.中間操作--映射");
        System.out.println("5.中間操作--排序");
        System.out.println("6.查找與匹配");
        System.out.println("7.歸約與收集");
        System.out.println("8.退出");
        System.out.println("請輸入數(shù)字:(例:6)");
        while (true) {
            int num = new Scanner(System.in).nextInt();
            if (num == 1) {
                test1();
            } else if (num == 2) {
                test2();
            } else if (num == 3) {
                test3();
            } else if (num == 4) {
                test4();
            } else if (num == 5) {
                test5();
            } else if (num == 6) {
                test6();
            } else if (num == 7) {
                test7();
            } else if (num == 8) {
                break;
            } else {
                System.err.println("您輸入的數(shù)字不正確,請重新輸入:");
            }
        }
    }

    /**
     * 創(chuàng)建 Stream
     */
    public static void test1() {

        // 1. 通過 Collections 系列集合提供的 stream()方法或 parallelStream()獲取
        List<String> list = Arrays.asList("aaa", "bbb", "ccc");

        list.forEach(System.out::println);
        // 2. 通過 Arrays 中的靜態(tài)方法獲取
        String[] strArr = {"aaa", "bbb", "ccc"};
        Stream<String> stream2 = Arrays.stream(strArr);

        // 3. 通過 Stream 類中的靜態(tài)方法 of()獲取
        Stream<String> stream3 = Stream.of("111", "222", "333");

        // 4. 創(chuàng)建無限流
        // 迭代
        Stream<Integer> stream4 = Stream.iterate(0, x -> x + 2);
        stream4.limit(20).forEach(System.out::println);

        // 生成
        Stream.generate(Math::random).limit(8).forEach(System.out::println);

    }

    /**
     * 中間操作--篩選與切片
     */
    public static void test2() {
        // distinct()比較 hash 值
        Stream<Person> stream = list.stream().filter(person -> person.getAge() > 20).distinct();

        // 終止,無終止岛抄,中間操作不執(zhí)行
        stream.forEach(System.out::println);

    }

    /**
     * 中間操作--映射
     */
    public static void test3() {
        System.out.println("---------------------map----------------------------");
        Stream<Person> stream1 = list.stream().map(person -> {
            person.setAge(person.getAge() + 10);
            return person;
        });
        stream1.forEach(System.out::println);

        System.out.println("----------------------map----------------------------");
        Stream<String> strs = list.stream().map(Person::getName);
        strs.forEach(System.out::println);

        System.out.println("----------------------flatMap----------------------------");
        List<String> strList = Arrays.asList("a,b,c", "d,e", "f,g,h,i");

        // 把 {{a,b,c},{d,e},{f,g,h,i}} 流轉(zhuǎn)化為 {a,b,c,d,e,f,g,h,i}
        Stream<String> stream2 = strList.stream().flatMap(s -> {
            String[] strArr = s.split(",");
            return Arrays.stream(strArr);
        });
        stream2.forEach(System.out::println);
    }

    /**
     * 中間操作--排序
     */
    public static void test4() {
        System.out.println("----------------------sorted Comparable----------------------------");
        // 使用 sorted()别惦,Person 類需實現(xiàn) Comparable 接口,重寫 compareTo()方法
        /*
         *   @Override
         *    public int compareTo(Person person) {
         *       return person.getAge() - this.age;
         *   }
         */
        list.stream().sorted().forEach(System.out::println);

        System.out.println("----------------------sorted Comparator----------------------------");

        System.out.println("----------------------age從大到小----------------------------");
        list.stream().sorted((p1, p2) -> p2.getAge() - p1.getAge()).forEach(System.out::println);

        System.out.println("----------------------age從小到大----------------------------");
        list.stream().sorted(Comparator.comparingInt(Person::getAge)).forEach(System.out::println);
    }

    /**
     * 中間操作--排序
     */
    public static void test5() {
        list.stream().peek(p -> p.setAge(25)).forEach(System.out::println);
    }

    /**
     * 查找與匹配
     */
    public static void test6() {
        System.out.println(list.stream().allMatch(x -> x.getGender().equals("男")));
        System.out.println(list.stream().noneMatch(x -> x.getGender().equals("男")));
        System.out.println(list.stream().anyMatch(x -> x.getGender().equals("男")));
        System.out.println(list.stream().findFirst().get());
        System.out.println(list.stream().findAny().get());
        System.out.println(list.stream().count());
        System.out.println(list.stream().max(Comparator.comparingInt(Person::getAge)).get());
        System.out.println(list.stream().min(Comparator.comparingInt(Person::getAge)).get());
    }

    /**
     * 歸約與收集
     */
    public static void test7() {
        Integer ageSum = list.stream().map(Person::getAge).reduce(Integer::sum).get();
        System.out.println("年齡總和:" + ageSum);

        Set<String> nameSet = list.stream().map(Person::getName).collect(Collectors.toSet());
        System.out.println(nameSet);

        HashSet<String> nameHashSet = list.stream().map(Person::getName).collect(Collectors.toCollection(HashSet::new));
        System.out.println(nameHashSet);

        Double avgAge = list.stream().collect(Collectors.averagingDouble(Person::getAge));
        System.out.println("平均年齡:" + avgAge);
        Integer a = list.stream().mapToInt(Person::getAge).sum();
        System.err.println(a);

    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末夫椭,一起剝皮案震驚了整個濱河市掸掸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌益楼,老刑警劉巖猾漫,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異感凤,居然都是意外死亡悯周,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門陪竿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來禽翼,“玉大人,你說我怎么就攤上這事族跛∪虻玻” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵礁哄,是天一觀的道長长酗。 經(jīng)常有香客問我,道長桐绒,這世上最難降的妖魔是什么夺脾? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮茉继,結(jié)果婚禮上咧叭,老公的妹妹穿的比我還像新娘。我一直安慰自己烁竭,他們只是感情好菲茬,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著派撕,像睡著了一般婉弹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上腥刹,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天马胧,我揣著相機與錄音,去河邊找鬼衔峰。 笑死佩脊,一個胖子當著我的面吹牛蛙粘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播威彰,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼出牧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了歇盼?” 一聲冷哼從身側(cè)響起舔痕,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎豹缀,沒想到半個月后伯复,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡邢笙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年啸如,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氮惯。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡叮雳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出妇汗,到底是詐尸還是另有隱情帘不,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布杨箭,位于F島的核電站寞焙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏互婿。R本人自食惡果不足惜棺弊,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望擒悬。 院中可真熱鬧,春花似錦稻艰、人聲如沸懂牧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽僧凤。三九已至,卻和暖如春元扔,著一層夾襖步出監(jiān)牢的瞬間躯保,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工澎语, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留途事,地道東北人验懊。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像尸变,于是被迫代替她去往敵國和親义图。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 篩選和切片 filter 方法 distinct 方法 limit 方法 skip 方法 謂詞篩選 Stream ...
    劉滌生閱讀 3,002評論 2 4
  • 1召烂、Stream簡介 Stream作為Java 8的一大亮點碱工,是對集合(Collection)、數(shù)組對象功能的增強...
    Albert_Yu閱讀 7,186評論 1 21
  • Stream(流)是一個來自數(shù)據(jù)源的元素隊列并支持聚合操作 元素是特定類型的對象奏夫,形成一個隊列怕篷。 - Java中的...
    興國First閱讀 885評論 0 0
  • 一. Stream的特性 Stream是Java 8新增的接口,Stream可以認為是一個高級版本的 Iterat...
    偷懶的掃地僧閱讀 84評論 0 0
  • 平時寫代碼的時候酗昼,經(jīng)常會對list進行操作廊谓,自從1.8之后有了stream 。能使用的話仔雷,就經(jīng)常使用了蹂析,現(xiàn)在在這歸...
    zycisbg閱讀 6,089評論 1 4