1.Collectors.groupingBy、Collectors.mapping:
參考博客:https://blog.csdn.net/L_fly_J/article/details/120164362
Person.java:

package com.mayikt.entity; public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } }
測試代碼:
package com.mayikt.stream; import com.mayikt.entity.Person; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class TestCollectorsMapping { public static void main(String[] args) { List<Person> list = new ArrayList<>(); list.add(new Person("Ram", 30)); list.add(new Person("Shyam", 20)); list.add(new Person("Shiv", 20)); list.add(new Person("Mahesh", 30)); String nameByAge = list.stream().collect(Collectors.mapping(Person::getName, Collectors.joining(",", "[", "]"))); System.out.println(nameByAge); nameByAge = list.stream().map(person -> person.getName()).collect(Collectors.joining(",", "[", "]")); System.out.println(nameByAge); Map<Integer, String> nameByAgeMap = list.stream().collect( Collectors.groupingBy(Person::getAge, Collectors.mapping(Person::getName, Collectors.joining(",", "[", "]")))); nameByAgeMap.forEach((k, v) -> System.out.println("Age:" + k + " Persons: " + v)); Map<Integer, List<String>> map2 = list.stream().collect( Collectors.groupingBy(Person::getAge, Collectors.mapping(Person::getName, Collectors.toList()))); System.out.println(map2); } }
[Ram,Shyam,Shiv,Mahesh] [Ram,Shyam,Shiv,Mahesh] 可以發現達到相同的效果 Age:20 Persons: [Shyam,Shiv] Age:30 Persons: [Ram,Mahesh] 封裝為Map后返回 {20=[Shyam, Shiv], 30=[Ram, Mahesh]}
2、Collectors.groupingBy的使用例子2:
查看代碼
package com.mayikt.entity;
public class UserAuth {
public String channelId;
public String authType;
public UserAuth(String channelId, String authType) {
this.channelId = channelId;
this.authType = authType;
}
public String getChannelId() {
return channelId;
}
public String getAuthType() {
return authType;
}
@Override
public String toString() {
return "UserAuth{" +
"channelId='" + channelId + '\'' +
", authType='" + authType + '\'' +
'}';
}
}
測試類:
package com.mayikt.stream;
import com.mayikt.entity.UserAuth;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class TestCollectorsGroupBy {
/**
* 假如有用戶認證,認證在渠道 + 認證方式上。
* 現在想把這些數據,按照authType分組作為map的key,將渠道歸集成list作為map的value,怎么做?
* @param args
*/
public static void main(String[] args) {
List<UserAuth> list = new ArrayList<>();
list.add(new UserAuth("EIBS", "B"));
list.add(new UserAuth("EMBS", "B"));
list.add(new UserAuth("EIBS", "K"));
Map<String, List<String>> authChannelMap0 =
list.stream().collect(Collectors.groupingBy(UserAuth::getAuthType, Collectors.mapping(UserAuth::getChannelId, Collectors.toList())));
System.out.println(authChannelMap0);
Map<String, String> authChannelMap2 =
list.stream().collect(Collectors.groupingBy(UserAuth::getAuthType, Collectors.mapping(UserAuth::getChannelId, Collectors.joining(",", "[", "]"))));
System.out.println(authChannelMap2);
}
}
console:
{B=[EIBS, EMBS], K=[EIBS]}
{B=[EIBS,EMBS], K=[EIBS]}
3.Collectors.groupingBy的三個方法
參考博客: https://blog.csdn.net/HO1_K/article/details/127572093
Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier)
Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream)
Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream)
classifier:鍵映射:該方法的返回值是鍵值對的 鍵
mapFactory:無參構造函數提供返回類型:提供一個容器初始化方法,用於創建新的 Map容器 (使用該容器存放值對)。
downstream:值映射:通過聚合方法將同鍵下的結果聚合為指定類型,該方法返回的是鍵值對的 值。
代碼示例:
Order:
查看代碼
package com.model;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* @description com.model
* @author: chengyu
* @date: 2023-10-08 19:25
*/
@Getter
@Setter
@ToString
@AllArgsConstructor
public class Order {
/**
* 機構號
*/
private Long deptSeq;
/**
* 訂單號
*/
private String orderNo;
/**
* 訂單金額
*/
private String amount;
}
package com.test.lamdba;
import com.model.Order;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
public class TestGroupingBy {
/**
* 將訂單列表按機構號分組
* groupingBy有三個方法
*/
public static void main(String[] args) {
List<Order> orderList = new ArrayList<>();
orderList.add(new Order(340000L, "orderNo_001", "10"));
orderList.add(new Order(340101L, "orderNo_002", "20"));
orderList.add(new Order(340309L, "orderNo_003", "5"));
orderList.add(new Order(340309L, "orderNo_004", "12"));
/**
* 將訂單按照機構號分組
* groupingBy的一個參數的方法,mapFactory是使用HashMap的,所以無序 值默認是ArrayList
*/
Map<Long, List<Order>> orderMap1 = orderList.stream().collect(Collectors.groupingBy(Order::getDeptSeq));
orderMap1.forEach((k, v) -> System.out.println("deptSeq:" + k + " Orders: " + v));
/**
* 將訂單按照機構號分組
* groupingBy的兩個參數的方法,指定了downstream
*/
Map<Long, String> orderMap2 = orderList.stream().collect(Collectors.groupingBy(Order::getDeptSeq, Collectors.mapping(Order::getOrderNo, Collectors.joining(","))));
orderMap2.forEach((k, v) -> System.out.println("deptSeq:" + k + " Orders: " + v));
/**
* 將訂單按照機構號分組,並且有序(原來list的順序)
* groupingBy的三個參數的方法,指定了mapFactory和downstream
*/
Map<Long, List<Order>> orderMap3 = orderList.stream().collect(Collectors.groupingBy(Order::getDeptSeq, TreeMap::new, Collectors.toList()));
orderMap3.forEach((k, v) -> System.out.println("deptSeq:" + k + " Orders: " + v));
}
}
deptSeq:340309 Orders: [Order(deptSeq=340309, orderNo=orderNo_003, amount=5), Order(deptSeq=340309, orderNo=orderNo_004, amount=12)]
deptSeq:340101 Orders: [Order(deptSeq=340101, orderNo=orderNo_002, amount=20)]
deptSeq:340000 Orders: [Order(deptSeq=340000, orderNo=orderNo_001, amount=10)]
deptSeq:340309 Orders: orderNo_003,orderNo_004
deptSeq:340101 Orders: orderNo_002
deptSeq:340000 Orders: orderNo_001
deptSeq:340000 Orders: [Order(deptSeq=340000, orderNo=orderNo_001, amount=10)]
deptSeq:340101 Orders: [Order(deptSeq=340101, orderNo=orderNo_002, amount=20)]
deptSeq:340309 Orders: [Order(deptSeq=340309, orderNo=orderNo_003, amount=5), Order(deptSeq=340309, orderNo=orderNo_004, amount=12)]
tips:
1.保證分組后的有序性的話,也可以自定義容器類型為LinkedHashMap。
2.也可以根據鍵的值,生成不同的范圍,這種范圍類型的鍵多數情況下都是通過比較來生成的,常用於統計指標,如:
查看代碼
// 根據兩級范圍 將學生划分及格不及格兩類
Map<Boolean, List<Student>> customRangeKey = students.stream().collect(Collectors.groupingBy(student -> student.getScore() > 60));
// 根據多級范圍 根據學生成績來評分
Map<String, List<Student>> customMultiRangeKey = students.stream().collect(Collectors.groupingBy(student -> {
if (student.getScore() < 60) {
return "C";
} else if (student.getScore() < 80) {
return "B";
}
return "A";
}));
3.分組統計功能,Collectors.counting:計數
查看代碼
// 計數
Map<String, Long> groupCount = students.stream().collect(Collectors.groupingBy(Student::getCourse, Collectors.counting()));
----