你需要了解的快捷開發 Java8 stream的使用(二) stream對List集合進行分組、彙總、排序等操作 Android兼容

目錄

1.Collectors 類

 2.分組方法

2.1groupingBy

2.2多級分組

2.3分組彙總

3.排序方法

3.1 sorted() / sorted((T, T) -> int)

4.安卓兼容

注意:


你需要了解的快捷開發 Java8 stream的使用(一) stream對List集合進行查詢、統計等操作

首先介紹一下Collectors 類的靜態工廠方法

1.Collectors 類

 

工廠方法 返回類型 作用
toList List<T> 把流中所有項目收集到一個 List
toSet Set<T> 把流中所有項目收集到一個 Set,刪除重複項
toCollection Collection<T> 把流中所有項目收集到給定的供應源創建的集合menuStream.collect(toCollection(), ArrayList::new)
counting Long 計算流中元素的個數
sumInt Integer 對流中項目的一個整數屬性求和
averagingInt Double 計算流中項目 Integer 屬性的平均值
summarizingInt IntSummaryStatistics 收集關於流中項目 Integer 屬性的統計值,例如最大、最小、 總和與平均值
joining String 連接對流中每個項目調用 toString 方法所生成的字符串collect(joining(", "))
maxBy Optional<T> 一個包裹了流中按照給定比較器選出的最大元素的 Optional, 或如果流爲空則爲 Optional.empty()
minBy Optional<T> 一個包裹了流中按照給定比較器選出的最小元素的 Optional, 或如果流爲空則爲 Optional.empty()
reducing 歸約操作產生的類型 從一個作爲累加器的初始值開始,利用 BinaryOperator 與流 中的元素逐個結合,從而將流歸約爲單個值累加int totalCalories = menuStream.collect(reducing(0, Dish::getCalories, Integer::sum));
collectingAndThen 轉換函數返回的類型 包裹另一個收集器,對其結果應用轉換函數int howManyDishes = menuStream.collect(collectingAndThen(toList(), List::size))
groupingBy Map<K, List<T>> 根據項目的一個屬性的值對流中的項目作問組,並將屬性值作 爲結果 Map 的鍵
partitioningBy Map<Boolean,List<T>> 根據對流中每個項目應用謂詞的結果來對項目進行分區

 2.分組方法

2.1groupingBy

使用 groupingBy() 將數據進行分組,最終返回一個 Map 類型。

根據部門對用戶列表進行分組。

/**
 * 使用 groupingBy() 分組 
 */
@Test
public void groupingByTest()
{
    //獲取用戶列表
    List<User> userList = UserService.getUserList();
 
    //根據部門對用戶列表進行分組
    Map<String,List<User>> userMap = userList.stream().collect(Collectors.groupingBy(User::getDepartment));
 
    //遍歷分組後的結果
    userMap.forEach((key, value) -> {
        System.out.println(key + ":");
        value.forEach(System.out::println);
        System.out.println("--------------------------------------------------------------------------");
    });
}

執行結果:

2.2多級分組

groupingBy 可以接受一個第二參數實現多級分組。

根據部門和性別對用戶列表進行分組。

/**
 * 使用 groupingBy() 多級分組 
 */
@Test
public void multGroupingByTest()
{
    //獲取用戶列表
    List<User> userList = UserService.getUserList();
 
    //根據部門和性別對用戶列表進行分組
    Map<String,Map<String,List<User>>> userMap = userList.stream()
            .collect(Collectors.groupingBy(User::getDepartment,Collectors.groupingBy(User::getSex)));
 
    //遍歷分組後的結果
    userMap.forEach((key1, map) -> {
        System.out.println(key1 + ":");
        map.forEach((key2,user)->
        {
            System.out.println(key2 + ":");
            user.forEach(System.out::println);
        });
        System.out.println("--------------------------------------------------------------------------");
    });
}

執行結果:

2.3分組彙總

根據部門進行分組,彙總各個部門用戶的平均年齡。

/**
 * 使用 groupingBy() 分組彙總 
 */
@Test
public void groupCollectTest()
{
    //獲取用戶列表
    List<User> userList = UserService.getUserList();
 
    //根據部門進行分組,彙總各個部門用戶的平均年齡
    Map<String, Double> userMap = userList.stream().collect(Collectors.groupingBy(User::getDepartment, Collectors.averagingInt(User::getAge)));
 
    //遍歷分組後的結果
    userMap.forEach((key, value) -> {
        System.out.println(key + "的平均年齡:" + value);
    });
}

執行結果:

3.排序方法

3.1 sorted() / sorted((T, T) -> int)

如果流中的元素的類實現了 Comparable 接口,即有自己的排序規則,那麼可以直接調用 sorted() 方法對元素進行排序,如 Stream。反之, 需要調用 sorted((T, T) -> int) 實現 Comparator 接口。

根據用戶年齡進行排序。

/**
 * 使用 sorted() 排序
 */
@Test
public void sortedTest()
{
    //獲取用戶列表
    List<User> userList = UserService.getUserList();
 
    //根據年齡排序(升序)
    userList = userList.stream().sorted((u1, u2) -> u1.getAge() - u2.getAge()).collect(Collectors.toList());
    //推薦:userList = userList.stream().sorted(Comparator.comparingInt(User::getAge)).collect(Collectors.toList());
    //降序:userList = userList.stream().sorted(Comparator.comparingInt(User::getAge).reversed()).collect(Collectors.toList());
 
    //遍歷用戶列表
    userList.forEach(System.out::println);
}

執行結果:

4.安卓兼容

如果是安卓使用stream會報錯提示SDK必須大於24才能使用

但是有用戶的機型SDK是小於24的,這樣肯定不行的。

可以在app\build.gradle中添加引用的庫;如下:

implementation 'com.annimon:stream:1.2.1'

注意:

在導包的時候,要導如下:

import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;

在使用的時候有一些不同

是使用Stream.of()

ArrayList<Person> arrayList = new ArrayList<>();
List<String> names = Stream.of(arrayList)
	.map(Person::getName)
	.collect(Collectors.toList());

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章