Java8?Stream之groupingBy分組使用解讀
Java8 Stream之groupingBy分組
本文主要講解:Java 8 Stream之Collectors.groupingBy()分組示例
Collectors.groupingBy()分組之常見(jiàn)用法
功能代碼:
?? ?/**
?? ? * 使用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)計(jì)每個(gè)分組的count
功能代碼:
?? ?/**
?? ? * 使用java8 stream groupingBy操作,按城市分組list統(tǒng)計(jì)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)計(jì)分組平均值
功能代碼:
?? ?/**
?? ? * 使用java8 stream groupingBy操作,按城市分組list并計(jì)算分組年齡平均值
?? ? */
?? ?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)計(jì)分組總值
功能代碼:
/**
?? ? * 使用java8 stream groupingBy操作,按城市分組list并計(jì)算分組銷(xiāo)售總值
?? ? */
?? ?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);
?? ??? ?});
?
?? ??? ?// 對(duì)Map按照分組銷(xiāo)售總值逆序排序
?? ??? ?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并通過(guò)join操作連接分組list中的對(duì)象的name 屬性使用逗號(hào)分隔
?? ? */
?? ?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() 分組之使用對(duì)象分組List
功能代碼:
?? ?/**
?? ? * 使用java8 stream groupingBy操作,通過(guò)Object對(duì)象的成員分組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() 分組之使用兩個(gè)成員分組List
功能代碼:
?? ?/**
?? ? * 使用java8 stream groupingBy操作, 基于city 和name 實(shí)現(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對(duì)結(jié)果去重
功能代碼
/**
?? ? * 使用java8 stream groupingBy操作, 基于Distinct 去重?cái)?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());
?? ??? ?});
?? ??? ?
?? ??? ?
?? ?}
?
?? ?/**
?? ? * 自定義重復(fù)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)計(jì)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并計(jì)算分組年齡平均值
?? ? */
?? ?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并計(jì)算分組銷(xiāo)售總值
?? ? */
?? ?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);
?? ??? ?});
?
?? ??? ?// 對(duì)Map按照分組銷(xiāo)售總值逆序排序
?? ??? ?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并通過(guò)join操作連接分組list中的對(duì)象的name 屬性使用逗號(hào)分隔
?? ? */
?? ?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操作,通過(guò)Object對(duì)象的成員分組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 實(shí)現(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 去重?cái)?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());
?? ??? ?});
?? ??? ?
?? ??? ?
?? ?}
?
?? ?/**
?? ? * 自定義重復(fù)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é)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot + vue 實(shí)現(xiàn)遞歸生成多級(jí)菜單(實(shí)例代碼)
這篇文章主要介紹了springboot + vue 實(shí)現(xiàn)遞歸生成多級(jí)菜單,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
Java try-with-resource語(yǔ)法使用解析
這篇文章主要介紹了Java try-with-resource語(yǔ)法使用解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
關(guān)于MyBatis Plus中使用or和and問(wèn)題
這篇文章主要介紹了關(guān)于MyBatis Plus中使用or和and問(wèn)題,需要的朋友可以參考下2020-12-12
SpringCloud中的@RefreshScope注解與使用場(chǎng)景方式
SpringCloud中的@RefreshScope注解用于動(dòng)態(tài)刷新Bean配置,解決外部配置變化時(shí)的問(wèn)題,避免重啟應(yīng)用,通過(guò)本文的詳細(xì)介紹,希望讀者能夠更好地掌握@RefreshScope的使用技巧,在實(shí)際項(xiàng)目中靈活應(yīng)用,提升微服務(wù)應(yīng)用的動(dòng)態(tài)配置管理能力2024-12-12
Springboot無(wú)法注入service問(wèn)題
這篇文章主要介紹了Springboot無(wú)法注入service的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
在CentOS系統(tǒng)上安裝Java?JDK?8簡(jiǎn)單步驟
最近購(gòu)買(mǎi)一臺(tái)新的云服務(wù)器,用于開(kāi)發(fā)學(xué)習(xí)使用,因此需要安裝很多的組件,下面這篇文章主要給大家介紹了關(guān)于在CentOS系統(tǒng)上安裝Java?JDK8的簡(jiǎn)單步驟,需要的朋友可以參考下2023-12-12

