使用Java Stream API将List按自定义分组规则转换成Map的一个例子-阿里云开发者社区

开发者社区> jerrywangsap> 正文

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

简介:
+关注继续查看

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

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

根据员工所在的城市进行分组:

结果分成了三组:

第一组的员工在上海:

第二组的员工在成都:

统计每组员工个数:


把员工进行分组,得分大于101分的在一组,小于等于101的在另一组:

分组结果:


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}}
          */
    }
}

本文来自云栖社区合作伙伴“汪子熙”,了解相关信息可以关注微信公众号"汪子熙"。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Kafka——使用java api进行pub &amp; sub
       之前用过老的api,但是最近在写消费的时候,发现之前老的api很多方法都out了,又去官网看了下最新的0.10.x的api. 1,producer org.apache.
890 0
Debian 使用 iptables-persistent 持久化 iptables 规则
RedHat系列下有比较好用的iptables管理工具,可以像控制服务进程一样来对防火墙进行管理及控制,Debian系发行版默认不开启iptables,当然也没有与之相关的能直接管理的工具了。 正常情况下,我们写入的iptables规则将会在系统重启时消失。
6232 0
List转换成为数组
toArraypublic  T[] toArray(T[] a)返回一个按照正确的顺序包含此列表中所有元素的数组;返回数组的运行时类型就是指定数组的运行时类型。如果列表能放入指定的数组,则返回放入此列表元素的数组。
722 0
+关注
2628
文章
0
问答
来源圈子
更多
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载