Java8?Stream之groupingBy分組使用解讀
更新時間:2023年04月26日 08:35:49 作者:Archie_java
這篇文章主要介紹了Java8?Stream之groupingBy分組使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
Java8 Stream之groupingBy分組
本文主要講解:Java 8 Stream之Collectors.groupingBy()分組示例
Collectors.groupingBy()分組之常見用法
功能代碼:
?? ?/** ?? ? * 使用java8 stream groupingBy操作,按城市分組list ?? ? */ ?? ?public void groupingByCity() { ?? ??? ?Map<String, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(Employee::getCity)); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ?}); ?? ?}
Collectors.groupingBy() 分組之統(tǒng)計每個分組的count
功能代碼:
?? ?/** ?? ? * 使用java8 stream groupingBy操作,按城市分組list統(tǒng)計count ?? ? */ ?? ?public void groupingByCount() { ?? ??? ?Map<String, Long> map = employees.stream() ?? ??? ??? ??? ?.collect(Collectors.groupingBy(Employee::getCity, Collectors.counting())); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ?}); ?? ?}
Collectors.groupingBy() 分組之統(tǒng)計分組平均值
功能代碼:
?? ?/** ?? ? * 使用java8 stream groupingBy操作,按城市分組list并計算分組年齡平均值 ?? ? */ ?? ?public void groupingByAverage() { ?? ??? ?Map<String, Double> map = employees.stream() ?? ??? ??? ??? ?.collect(Collectors.groupingBy(Employee::getCity, Collectors.averagingInt(Employee::getAge))); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ?}); ?? ?}
Collectors.groupingBy() 分組之統(tǒng)計分組總值
功能代碼:
/** ?? ? * 使用java8 stream groupingBy操作,按城市分組list并計算分組銷售總值 ?? ? */ ?? ?public void groupingBySum() { ?? ??? ?Map<String, Long> map = employees.stream() ?? ??? ??? ??? ?.collect(Collectors.groupingBy(Employee::getCity, Collectors.summingLong(Employee::getAmount))); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ?}); ? ?? ??? ?// 對Map按照分組銷售總值逆序排序 ?? ??? ?Map<String, Long> sortedMap = new LinkedHashMap<>(); ?? ??? ?map.entrySet().stream().sorted(Map.Entry.<String, Long> comparingByValue().reversed()) ?? ??? ??? ??? ?.forEachOrdered(e -> sortedMap.put(e.getKey(), e.getValue())); ? ?? ??? ?sortedMap.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ?}); ?? ?}
Collectors.groupingBy() 分組之Join分組List
功能代碼:
/** ?? ? * 使用java8 stream groupingBy操作,按城市分組list并通過join操作連接分組list中的對象的name 屬性使用逗號分隔 ?? ? */ ?? ?public void groupingByString() { ?? ??? ?Map<String, String> map = employees.stream().collect(Collectors.groupingBy(Employee::getCity, ?? ??? ??? ??? ?Collectors.mapping(Employee::getName, Collectors.joining(", ", "Names: [", "]")))); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ?}); ?? ?}
Collectors.groupingBy() 分組之轉(zhuǎn)換分組結(jié)果List -> List
功能代碼:
/** ?? ? * 使用java8 stream groupingBy操作,按城市分組list,將List轉(zhuǎn)化為name的List ?? ? */ ?? ?public void groupingByList() { ?? ??? ?Map<String, List<String>> map = employees.stream().collect( ?? ??? ??? ??? ?Collectors.groupingBy(Employee::getCity, Collectors.mapping(Employee::getName, Collectors.toList()))); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ??? ?v.stream().forEach(item -> { ?? ??? ??? ??? ?System.out.println("item = " + item); ?? ??? ??? ?}); ?? ??? ?}); ?? ?}
Collectors.groupingBy() 分組之轉(zhuǎn)換分組結(jié)果List -> Set
功能代碼:
?? ?/** ?? ? * 使用java8 stream groupingBy操作,按城市分組list,將List轉(zhuǎn)化為name的Set ?? ? */ ?? ?public void groupingBySet() { ?? ??? ?Map<String, Set<String>> map = employees.stream().collect( ?? ??? ??? ??? ?Collectors.groupingBy(Employee::getCity, Collectors.mapping(Employee::getName, Collectors.toSet()))); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ??? ?v.stream().forEach(item -> { ?? ??? ??? ??? ?System.out.println("item = " + item); ?? ??? ??? ?}); ?? ??? ?}); ?? ?}
Collectors.groupingBy() 分組之使用對象分組List
功能代碼:
?? ?/** ?? ? * 使用java8 stream groupingBy操作,通過Object對象的成員分組List ?? ? */ ?? ?public void groupingByObject() { ?? ??? ?Map<Manage, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(item -> { ?? ??? ??? ?return new Manage(item.getName()); ?? ??? ?})); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ?}); ?? ?}
Collectors.groupingBy() 分組之使用兩個成員分組List
功能代碼:
?? ?/** ?? ? * 使用java8 stream groupingBy操作, 基于city 和name 實現(xiàn)多次分組 ?? ? */ ?? ?public void groupingBys() { ?? ??? ?Map<String, Map<String, List<Employee>>> map = employees.stream() ?? ??? ??? ??? ?.collect(Collectors.groupingBy(Employee::getCity, Collectors.groupingBy(Employee::getName))); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ??? ?v.forEach((i, j) -> { ?? ??? ??? ??? ?System.out.println(i + " = " + j); ?? ??? ??? ?}); ?? ??? ?}); ?? ?}
自定義Distinct對結(jié)果去重
功能代碼
/** ?? ? * 使用java8 stream groupingBy操作, 基于Distinct 去重數(shù)據(jù) ?? ? */ ?? ?public void groupingByDistinct() { ?? ??? ?List<Employee> list = employees.stream().filter(distinctByKey(Employee :: getCity)) ?? ??? ??? ??? ?.collect(Collectors.toList());; ? ?? ??? ?list.stream().forEach(item->{ ?? ??? ??? ?System.out.println("city = " + item.getCity()); ?? ??? ?}); ?? ??? ? ?? ??? ? ?? ?} ? ?? ?/** ?? ? * 自定義重復key 規(guī)則 ?? ? * @param keyExtractor ?? ? * @return ?? ? */ ?? ?private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { ?? ??? ?Set<Object> seen = ConcurrentHashMap.newKeySet(); ?? ??? ?return t -> seen.add(keyExtractor.apply(t)); ?? ?}
完整源代碼:
package com.stream; ? import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; ? /** ?* Java 8 Stream 之groupingBy 分組講解 ?*? ?* @author zzg ?* ?*/ public class Java8GroupBy { ? ?? ?List<Employee> employees = new ArrayList<Employee>(); ? ?? ?/** ?? ? * 數(shù)據(jù)初始化 ?? ? */ ?? ?public void init() { ?? ??? ?List<String> citys = Arrays.asList("湖南", "湖北", "江西", "廣西 "); ?? ??? ?for (int i = 0; i < 10; i++) { ?? ??? ??? ?Random random = new Random(); ?? ??? ??? ?Integer index = random.nextInt(4); ?? ??? ??? ?Employee employee = new Employee(citys.get(index), "姓名" + i, (random.nextInt(4) * 10 - random.nextInt(4)), ?? ??? ??? ??? ??? ?(random.nextInt(4) * 1000 - random.nextInt(4))); ?? ??? ??? ?employees.add(employee); ?? ??? ?} ?? ?} ? ?? ?/** ?? ? * 使用java8 stream groupingBy操作,按城市分組list ?? ? */ ?? ?public void groupingByCity() { ?? ??? ?Map<String, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(Employee::getCity)); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ?}); ?? ?} ? ?? ?/** ?? ? * 使用java8 stream groupingBy操作,按城市分組list統(tǒng)計count ?? ? */ ?? ?public void groupingByCount() { ?? ??? ?Map<String, Long> map = employees.stream() ?? ??? ??? ??? ?.collect(Collectors.groupingBy(Employee::getCity, Collectors.counting())); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ?}); ?? ?} ? ?? ?/** ?? ? * 使用java8 stream groupingBy操作,按城市分組list并計算分組年齡平均值 ?? ? */ ?? ?public void groupingByAverage() { ?? ??? ?Map<String, Double> map = employees.stream() ?? ??? ??? ??? ?.collect(Collectors.groupingBy(Employee::getCity, Collectors.averagingInt(Employee::getAge))); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ?}); ?? ?} ? ?? ?/** ?? ? * 使用java8 stream groupingBy操作,按城市分組list并計算分組銷售總值 ?? ? */ ?? ?public void groupingBySum() { ?? ??? ?Map<String, Long> map = employees.stream() ?? ??? ??? ??? ?.collect(Collectors.groupingBy(Employee::getCity, Collectors.summingLong(Employee::getAmount))); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ?}); ? ?? ??? ?// 對Map按照分組銷售總值逆序排序 ?? ??? ?Map<String, Long> sortedMap = new LinkedHashMap<>(); ?? ??? ?map.entrySet().stream().sorted(Map.Entry.<String, Long> comparingByValue().reversed()) ?? ??? ??? ??? ?.forEachOrdered(e -> sortedMap.put(e.getKey(), e.getValue())); ? ?? ??? ?sortedMap.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ?}); ?? ?} ? ?? ?/** ?? ? * 使用java8 stream groupingBy操作,按城市分組list并通過join操作連接分組list中的對象的name 屬性使用逗號分隔 ?? ? */ ?? ?public void groupingByString() { ?? ??? ?Map<String, String> map = employees.stream().collect(Collectors.groupingBy(Employee::getCity, ?? ??? ??? ??? ?Collectors.mapping(Employee::getName, Collectors.joining(", ", "Names: [", "]")))); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ?}); ?? ?} ? ?? ?/** ?? ? * 使用java8 stream groupingBy操作,按城市分組list,將List轉(zhuǎn)化為name的List ?? ? */ ?? ?public void groupingByList() { ?? ??? ?Map<String, List<String>> map = employees.stream().collect( ?? ??? ??? ??? ?Collectors.groupingBy(Employee::getCity, Collectors.mapping(Employee::getName, Collectors.toList()))); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ??? ?v.stream().forEach(item -> { ?? ??? ??? ??? ?System.out.println("item = " + item); ?? ??? ??? ?}); ?? ??? ?}); ?? ?} ? ?? ?/** ?? ? * 使用java8 stream groupingBy操作,按城市分組list,將List轉(zhuǎn)化為name的Set ?? ? */ ?? ?public void groupingBySet() { ?? ??? ?Map<String, Set<String>> map = employees.stream().collect( ?? ??? ??? ??? ?Collectors.groupingBy(Employee::getCity, Collectors.mapping(Employee::getName, Collectors.toSet()))); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ??? ?v.stream().forEach(item -> { ?? ??? ??? ??? ?System.out.println("item = " + item); ?? ??? ??? ?}); ?? ??? ?}); ?? ?} ? ?? ?/** ?? ? * 使用java8 stream groupingBy操作,通過Object對象的成員分組List ?? ? */ ?? ?public void groupingByObject() { ?? ??? ?Map<Manage, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(item -> { ?? ??? ??? ?return new Manage(item.getName()); ?? ??? ?})); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ?}); ?? ?} ? ?? ?/** ?? ? * 使用java8 stream groupingBy操作, 基于city 和name 實現(xiàn)多次分組 ?? ? */ ?? ?public void groupingBys() { ?? ??? ?Map<String, Map<String, List<Employee>>> map = employees.stream() ?? ??? ??? ??? ?.collect(Collectors.groupingBy(Employee::getCity, Collectors.groupingBy(Employee::getName))); ? ?? ??? ?map.forEach((k, v) -> { ?? ??? ??? ?System.out.println(k + " = " + v); ?? ??? ??? ?v.forEach((i, j) -> { ?? ??? ??? ??? ?System.out.println(i + " = " + j); ?? ??? ??? ?}); ?? ??? ?}); ?? ?} ? ?? ?/** ?? ? * 使用java8 stream groupingBy操作, 基于Distinct 去重數(shù)據(jù) ?? ? */ ?? ?public void groupingByDistinct() { ?? ??? ?List<Employee> list = employees.stream().filter(distinctByKey(Employee :: getCity)) ?? ??? ??? ??? ?.collect(Collectors.toList());; ? ?? ??? ?list.stream().forEach(item->{ ?? ??? ??? ?System.out.println("city = " + item.getCity()); ?? ??? ?}); ?? ??? ? ?? ??? ? ?? ?} ? ?? ?/** ?? ? * 自定義重復key 規(guī)則 ?? ? * @param keyExtractor ?? ? * @return ?? ? */ ?? ?private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { ?? ??? ?Set<Object> seen = ConcurrentHashMap.newKeySet(); ?? ??? ?return t -> seen.add(keyExtractor.apply(t)); ?? ?} ? ?? ?public static void main(String[] args) { ?? ??? ?// TODO Auto-generated method stub ?? ??? ?Java8GroupBy instance = new Java8GroupBy(); ?? ??? ?instance.init(); ?? ??? ?instance.groupingByCity(); ?? ??? ?instance.groupingByCount(); ?? ??? ?instance.groupingByAverage(); ?? ??? ?instance.groupingBySum(); ?? ??? ?instance.groupingByString(); ?? ??? ?instance.groupingByList(); ?? ??? ?instance.groupingBySet(); ?? ??? ?instance.groupingByObject(); ?? ??? ?instance.groupingBys(); ?? ??? ?instance.groupingByDistinct(); ? ?? ?} ? ?? ?class Employee { ?? ??? ?private String city; ?? ??? ?private String name; ?? ??? ?private Integer age; ?? ??? ?private Integer amount; ? ?? ??? ?public String getCity() { ?? ??? ??? ?return city; ?? ??? ?} ? ?? ??? ?public void setCity(String city) { ?? ??? ??? ?this.city = city; ?? ??? ?} ? ?? ??? ?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 Integer getAmount() { ?? ??? ??? ?return amount; ?? ??? ?} ? ?? ??? ?public void setAmount(Integer amount) { ?? ??? ??? ?this.amount = amount; ?? ??? ?} ? ?? ??? ?public Employee(String city, String name, Integer age, Integer amount) { ?? ??? ??? ?super(); ?? ??? ??? ?this.city = city; ?? ??? ??? ?this.name = name; ?? ??? ??? ?this.age = age; ?? ??? ??? ?this.amount = amount; ?? ??? ?} ? ?? ??? ?public Employee() { ?? ??? ??? ?super(); ?? ??? ?} ?? ?} ? ?? ?class Manage { ?? ??? ?private String name; ? ?? ??? ?public String getName() { ?? ??? ??? ?return name; ?? ??? ?} ? ?? ??? ?public void setName(String name) { ?? ??? ??? ?this.name = name; ?? ??? ?} ? ?? ??? ?public Manage(String name) { ?? ??? ??? ?super(); ?? ??? ??? ?this.name = name; ?? ??? ?} ? ?? ??? ?public Manage() { ?? ??? ??? ?super(); ?? ??? ?} ?? ?} ? }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot?整合mysql實現(xiàn)版本管理通用最新解決方案
當springboot微服務(wù)項目完成從開發(fā)到測試全流程后,通常來說,最終交付產(chǎn)物是一個完整的安裝包,這篇文章主要介紹了springboot?整合mysql實現(xiàn)版本管理通用解決方案,需要的朋友可以參考下2023-08-08SpringBoot整合Redis實現(xiàn)常用功能超詳細過程
這篇文章主要介紹了SpringBoot整合Redis實現(xiàn)常用功能,登陸功能是每個項目必備的功能吧,但是想設(shè)計好,卻是很難,下面介紹兩種登陸功能的解決方式,需要的朋友可以參考下2022-08-08mybatis-plus 使用Condition拼接Sql語句各方法的用法
這篇文章主要介紹了mybatis-plus 使用Condition拼接Sql語句各方法的用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07