1. 程式人生 > >java8 分組、List轉map、過濾、排序等

java8 分組、List轉map、過濾、排序等

定義Test物件:

public class Test {
    private Integer id;

    private String name;

    private BigDecimal money;

    public Test(){}

    public Test(Integer id, String name, BigDecimal money){
        this.id = id;
        this.name = name;
        this.money = money
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public BigDecimal getMoney() {
        return money;
    }

    public void setMoney(BigDecimal money) {
        this.money = money;
    }
}

新增一些測試資料:

List<Test> list= new ArrayList<>();
 
Test test1 =  new Test(1,"test1",new BigDecimal("3.5"));
Test test2 = new Test(1,"test2",new BigDecimal("6"));
Test test3 =  new Test(2,"test3",new BigDecimal("2.2"));
 
list.add(test1);
list.add(test2);
list.add(test3);

1.排序

Collections.sort(list, (s1, s2) -> s1.getMoney().toString().compareTo(s2.getMoney().toString()));

System.out.println("list:" + list);
list:[Test[id=2,name=test3,money=2.2], Test[id=1,name=test1,money=3.5], Test[id=1,name=test2,money=6]]


2.分組

List裡面的物件元素,以某個屬性來分組,例如,以id分組,將id相同的放在一起:

Map<Integer, List<Test>> map = list.stream().collect(Collectors.groupingBy(Test::getId));
 
System.out.println("result:" + map);
result:{1=[Test[id=1,name=test1,money=3.5], Test[id=1,name=test2,money=6]], 2=[Test[id=2,name=test3,money=2.2]]}

3.將List<物件>轉換為List<物件屬性>

List<String> filterList = list.stream().map(Test::getName).collect(Collectors.toList());

System.out.println("filterList:" + filterList);

filterList:[test1, test2, test3]


4.List轉Map

id為key,apple物件為value:

/**
 * 注意:如果集合物件有重複的key,會報錯java.lang.IllegalStateException: Duplicate key test1
 *  可以用 (k1,k2)->k1 來設定,如果有重複的key,則保留k1,捨棄k2
 */
Map<Integer, Test> map = list.stream().collect(Collectors.toMap(Test::getId, t -> t,(k1,k2)->k1));
System.out.println("result:" + map);
result:{1=Test[id=1,name=test1,money=3.5], 2=Test[id=2,name=test3,money=2.2]}

 id為key,name為value:

Map<Integer, String> map = list.stream().collect(Collectors.toMap(Test::getId,Test::getName,(k1,k2)->k1));
System.out.println("result:" + map);
result:{1=test1, 2=test3}


5.List過濾:

//過濾出符合條件的資料
List<Test> filterList = list.stream().filter(t -> t.getName().equals("test2")).collect(Collectors.toList());
 
System.out.println("filterList:" + filterList);
filterList:[Test[id=1,name=test2,money=6]]


6.求和:

//計算 總金額
BigDecimal totalMoney = list.stream().map(Test::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
System.err.println("totalMoney:"+totalMoney);  //totalMoney:11.7

7.查詢最大 最小值:

Optional<Test> max = list.stream().
                collect(Collectors.maxBy(Comparator.comparing(Test::getMoney)));
max.ifPresent(System.out::println);

Optional<Test> min = list.stream().
                collect(Collectors.minBy(Comparator.comparing(Test::getMoney)));
min.ifPresent(System.out::println);

8.去重

List<Test> newList = list.stream().collect(
                collectingAndThen(
                        toCollection(() -> new TreeSet<>(comparingLong(Test::getId))), ArrayList::new)
        );
System.out.println("去重List:" + newList);

下表展示 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>> 根據對流中每個專案應用謂詞的結果來對專案進行分割槽