成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java8-10-Stream分組與分區(qū)詳解

shengguo / 1755人閱讀

摘要:上一篇我們介紹了的概念與實際的一些操作,本篇我們繼續(xù)來學習的另一個重要操作,分組與分區(qū)。注意到分組后的返回類型是,結(jié)果集中會將作為,對應(yīng)的集合作為返回。

上一篇我們介紹了Strem的概念與實際的一些操作,本篇我們繼續(xù)來學習Stream的另一個重要操作,分組與分區(qū)。
我們在上一篇介紹Stream的操作時,會經(jīng)常使用到Collectors這個類,這個類實際上是一個封裝了很多常用的匯聚操作的一個工廠類。我們之前用到過

//將結(jié)果匯聚到ArrayList中
Collectors.toList();
//將結(jié)果匯聚到HashSet中
Collectors.toSet();

以及更為通用的

//將結(jié)果匯聚到一個指定類型的集合中
Collectors.toCollection(Supplier collectionFactory);

Stream分組

在實際開發(fā)中,對于將一個集合的內(nèi)容進行分組或分區(qū)這種需求也非常常見,所以我們繼續(xù)學習下Collectors類中的groupingBy和partitioningBy方法。

public static Collector groupingBy(Function classifier){
    //...
}

groupingBy接收一個Function類型的變量classifier,classifier被稱作分類器,收集器會按著classifier作為key對集合元素進行分組,然后返回Collector收集器對象,假如現(xiàn)在有一個實體Student

public class Student {
    private String name;
    private int score;
    private int age;

    public Student(String name,int score,int age){
        this.name = name;
        this.score = score;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public int getAge() {
        return age;
    }

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

我們現(xiàn)在按Student的name進行分組,如果使用sql來表示就是select * from student group by name; 再看下使用Stream的方式

Map> collect = students.stream().collect(Collectors.groupingBy(Student::getName));

這里我們使用方法引用(類名::實例方法名)替代lambda表達式(s -> s.getName())的方式來指定classifier分類器,使集合按Student的name來分組。
注意到分組后的返回類型是Map>,結(jié)果集中會將name作為key,對應(yīng)的Student集合作為value返回。
那如果按name分組后,想求出每組學生的數(shù)量,就需要借助groupingBy另一個重載的方法

public static Collector groupingBy(Function classifier,Collector downstream){
    //...
}

第二個參數(shù)downstream還是一個收集器Collector對象,也就是說我們可以先將classifier作為key進行分組,然后將分組后的結(jié)果交給downstream收集器再進行處理

//按name分組 得出每組的學生數(shù)量 使用重載的groupingBy方法,第二個參數(shù)是分組后的操作
Map collect1 = students.stream().collect(Collectors.groupingBy(Student::getName, Collectors.counting()));

Collectors類這里也幫我們封裝好了用于統(tǒng)計數(shù)量的counting()方法,這里先了解一下counting()就是將收集器中元素求總數(shù)即可,后續(xù)我們會再深入源碼學習。

我們還可以對分組后的數(shù)據(jù)求平均值

Map collect2 = students.stream().collect(Collectors.groupingBy(Student::getName, Collectors.averagingDouble(Student::getScore)));

averagingDouble方法接收一個ToDoubleFunction參數(shù)

@FunctionalInterface
public interface ToDoubleFunction {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    double applyAsDouble(T value);
}

ToDoubleFunction實際上也是Function系列函數(shù)式接口中的其中一個特例,接收一個參數(shù),返回Double類型(這里是接收一個Student返回score)。因為分組后的集合中每個元素是Student類型的,所以我們無法直接對Student進行求平均值

//偽代碼
Collectors.averagingDouble(Student))

所以需要將Student轉(zhuǎn)成score再求平均值,Collectors.averagingDouble(Student::getScore))。

Stream分區(qū)

針對上面的Student,我們現(xiàn)在再加一個需求,分別統(tǒng)計一下及格和不及格的學生(分數(shù)是否>=60)
這時候符合Stream分區(qū)的概念了,Stream分區(qū)會將集合中的元素按條件分成兩部分結(jié)果,key是Boolean類型,value是結(jié)果集,滿足條件的key是true,我們看下示例。

Map> collect3 = students.stream().collect(Collectors.partitioningBy(student -> student.getScore() >= 60));
System.out.println(collect3.get(true));//輸出及格的Student
System.out.println(collect3.get(false));//輸出不及格的Student

partitioningBy方法接收一個Predicate作為分區(qū)判斷的依據(jù),滿足條件的元素放在key為true的集合中,反之放在key為false的集合中

//partitioningBy方法
public static Collector partitioningBy(Predicate predicate) {
    return partitioningBy(predicate, toList());
}

下一篇

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/70778.html

相關(guān)文章

  • 《從0到1學習Flink》—— Flink Data transformation(轉(zhuǎn)換)

    摘要:這些切片稱為窗口。函數(shù)允許對常規(guī)數(shù)據(jù)流進行分組。通常,這是非并行數(shù)據(jù)轉(zhuǎn)換,因為它在非分區(qū)數(shù)據(jù)流上運行。 showImg(https://segmentfault.com/img/remote/1460000017874226?w=1920&h=1271); 前言 在第一篇介紹 Flink 的文章 《《從0到1學習Flink》—— Apache Flink 介紹》 中就說過 Flink ...

    oujie 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<