使用Java Stream API将List按自定义分组规则转换成Map的一个例子

简介: 使用Java Stream API将List按自定义分组规则转换成Map的一个例子

本文完整测试代码见文末。

测试数据是List里的4个员工对象实例:image.pngimage.pngimage.pngimage.pngimage.pngimage.png

package java8;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Consumer;
import java.util.stream.Collectors;
class Employee {
  private String city;
  private String name;
  private int score;
  public Employee(String name, String city, int score){
    this.city = city;
    this.name = name;
    this.score = score;
  }
  public String getCity(){
    System.out.println("city: " + this.city);
    return this.city;
  }
  public String getName() {
    return this.name;
  }
  public int getScore() {
    return this.score;
  }
  @Override
    public String toString() {
        return String.format("Employee: " + this.name + " city: " + this.city);
    }
}
class Person {
    private String name;
    private int age;
    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return String.format("Person{name='%s', age=%d}", name, age);
    }
}
// Jerry 2016-01-15 20:51PM ? 多用于extends generic的type,接受所有Object的sub class
public class StreamTest {
  private static void printMap(Map<? extends Object, ? extends Object> map) {
     for(Entry<? extends Object, ? extends Object> entry:map.entrySet()) {
          System.out.println("key = " + entry.getKey() + " , Value = " + entry.getValue());
       }
  }
  public static void main(String[] args) {
    ArrayList<Employee> employees = new ArrayList<Employee>();
    employees.add(new Employee("A", "Shanghai",100));
    employees.add(new Employee("B", "Chengdu",101));
    employees.add(new Employee("C", "Shenzhen",102));
    employees.add(new Employee("D", "Chengdu",104));
    // group by City
    Map<String, List<Employee>> employeesByCity =
        employees.stream().collect( Collectors.groupingBy(Employee::getCity));
    //  default void forEach(Consumer<? super T> action) {
    for(Map.Entry<String, List<Employee>> entry:employeesByCity.entrySet()) {
        System.out.println("key= " + entry.getKey() + " , Value = " + entry.getValue());
        entry.getValue().forEach(System.out::println);
     }
     // 2016-01-15 20:37PM 
     Consumer<Employee> aa = a -> { System.out.println("Employee: " + a.getName() + " : " +  a.getScore()); };
     List<Employee> chengduEmployee = employeesByCity.get("Chengdu");
     chengduEmployee.forEach(aa);
     // test for counting
     Map<String, Long> employeesByCity2 = 
         employees.stream().collect( Collectors.groupingBy(Employee::getCity, Collectors.counting()));
     printMap(employeesByCity2);
     // calculate average score
     Map<String, Double> employeesByCity3 = 
         employees.stream().collect( Collectors.groupingBy(Employee::getCity,
             Collectors.averagingInt(Employee::getScore)));
     printMap(employeesByCity3);
    /*Stream<Person> people = Stream.of(new Person("Paul", 24), new Person("Mark", 30), new Person("Will", 28));
    Map<Integer, List<String>> peopleByAge = people.collect(groupingBy(p -> p.age, mapping((Person p) -> p.name, toList())));
    System.out.println(peopleByAge);*/
     /*
      * 分区是一种特殊的分组,结果 map 至少包含两个不同的分组——一个true,一个false。
      * 例如,如果想找出最优秀的员工,你可以将所有雇员分为两组,一组销售量大于 N,
      * 另一组小于 N,使用 partitioningBy 收集器:
      */
     System.out.println("partition result");
     Map<Boolean, List<Employee>> partitioned =
         employees.stream().collect(Collectors.partitioningBy(e -> e.getScore() > 101));
     printMap(partitioned);
     /*
      * 你也可以将 groupingBy 收集器传递给 partitioningBy 收集器来将联合使用分区和分组。例如,你可以统计每个分区中的每个城市的雇员人数:
    Map<Boolean, Map<String, Long>> result =
    employees.stream().collect(partitioningBy(e -> e.getNumSales() > 150,
    groupingBy(Employee::getCity, counting())));
    这样会生成一个二级 Map:
    {false={London=1}, true={New York=1, Hong Kong=1, London=1}}
      */
  }
}


相关文章
|
18天前
|
Java
Java 变量命名规则
4月更文挑战第6天
|
1月前
|
Java API 数据处理
Java 8新特性之Stream API详解
【2月更文挑战第22天】本文将深入探讨Java 8中引入的Stream API,这是一种基于函数式编程的新特性,用于处理集合数据。我们将详细介绍Stream的基本概念、操作方法以及在实际开发中的应用,帮助读者更好地理解和使用这一强大的工具。
|
1月前
|
Java API
Java 8新特性之Lambda表达式与Stream API
【2月更文挑战第21天】本文将介绍Java 8中的两个重要特性:Lambda表达式和Stream API。Lambda表达式是Java 8中引入的一种新的编程语法,它允许我们将函数作为参数传递给方法,从而使代码更加简洁、易读。Stream API是一种用于处理集合的新API,它提供了一种高效且易于使用的处理数据的方式。本文将通过实例讲解这两个特性的基本用法以及它们如何帮助我们编写更简洁、高效的Java代码。
|
3天前
|
Java
Java基础知识整理,驼峰规则、流程控制、自增自减
在这一篇文章中我们总结了包括注释、关键字、运算符的Java基础知识点,今天继续来聊一聊命名规则(驼峰)、流程控制、自增自减。
34 3
|
10天前
|
存储 安全 Java
说说Java 8 引入的Stream API
说说Java 8 引入的Stream API
12 0
|
11天前
|
分布式计算 Java API
Java 8新特性之Lambda表达式与Stream API
【4月更文挑战第16天】本文将介绍Java 8中的两个重要新特性:Lambda表达式和Stream API。Lambda表达式是Java 8中引入的一种新的编程语法,它允许我们将函数作为参数传递给其他方法,从而使代码更加简洁、易读。Stream API是Java 8中引入的一种新的数据处理方式,它允许我们以声明式的方式处理数据,从而使代码更加简洁、高效。本文将通过实例代码详细讲解这两个新特性的使用方法和优势。
|
14天前
|
存储 Java 关系型数据库
掌握Java 8 Stream API的艺术:详解流式编程(一)
掌握Java 8 Stream API的艺术:详解流式编程
47 1
|
1月前
|
分布式计算 Java 程序员
Java 8新特性之Lambda表达式与Stream API
本文将详细介绍Java 8中的两个重要新特性:Lambda表达式和Stream API。Lambda表达式是Java 8中引入的一种简洁、匿名的函数表示方法,它允许我们将函数作为参数传递给其他方法。而Stream API则是一种新的数据处理方式,它允许我们以声明式的方式处理数据,从而提高代码的可读性和可维护性。通过本文的学习,你将能够掌握Lambda表达式和Stream API的基本用法,以及如何在项目中应用这两个新特性。
31 10
|
1月前
|
Java API 数据处理
Java 8新特性之Lambda表达式与Stream API
本文将介绍Java 8中的两个重要特性:Lambda表达式和Stream API。Lambda表达式是一种新的语法结构,允许我们将函数作为参数传递给方法。而Stream API则是一种处理数据的新方式,它允许我们对数据进行更简洁、更高效的操作。通过学习这两个特性,我们可以编写出更简洁、更易读的Java代码。
|
1月前
|
Java API 数据处理
Java 8新特性之Lambda表达式和Stream API
【2月更文挑战第27天】本文将介绍Java 8中的两个重要特性:Lambda表达式和Stream API。Lambda表达式是一种新的编程语法,它允许我们将函数作为参数传递给方法,从而使代码更加简洁。Stream API是一种处理数据的新方法,它可以让我们以声明式方式处理数据,提高代码的可读性和可维护性。