使用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}} */ } }
本文来自云栖社区合作伙伴“汪子熙”,了解相关信息可以关注微信公众号"汪子熙"。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
SAP ABAP里存在Java List这种集合工具类么?CL_OBJECT_COLLECTION了解一下
文章标题的incident含义:在企业级软件领域里,当客户使用软件提供商的软件,遇到各种问题或故障,可以使用专门的工具,向软件供应商寻求帮助。我们通常称这种工具创建的帮助请求(Support Request)为incident. 今天这篇文章无关具体的技术。Jerry最近使用微软Azure云平台时遇到一个问题,通过Azure提供的Support工具向微软提交incident的过程中,感叹自己十多年来一直是修bug的命,这次终于翻身了,由我给另一家软件公司报bug,体验了一回当上帝的感觉。 我在SAP这些年,一共处理过317个客户incidents(当然并不是所有的都是Jerry修复的,包括我分析后转手到其他部分的也算). 我们Commerce Cloud团队使用Azure提供的Function create API在Azure上创建Lambda Function,过程中遇到一些问题,详见Jerry之前的文章:SAP ABAP应用服务器的HTTP响应状态码(Status Code). 在排除了问题不是我们消费端代码引起之后,我开始给Azure报incident. 虽然Azure的字面意思...
- 下一篇
ABAP面试题系列:写一组会出现死锁(Deadlock)的ABAP程序
我们在计算机操作系统这门专业课上,学过死锁(Deadlock)的概念:两个或两个以上的进程(或线程)在执行过程中,由于竞争资源而造成的一种阻塞的现象,称为死锁。若无外力干预,这些处于死锁状态的进程将永远处于互相等待的阻塞状态中。 正好我儿子走到我电脑前看到文章标题,好奇地问我什么是死锁。我解释道,“假设你和白妹妹(他的玩伴)手上都有一张奥特曼白金卡,你特别想要白妹妹手上那张白金卡,白妹妹也特别想要你手上那张白金卡。你们都想让对方把他/她手上那张卡送给你们,但你们都舍不得把自己手上那张卡送出去。这就是死锁。” 儿子又问,那这种情况咋办。 我说,只有靠大人的介入。比如你老爸出马,把你们手中两张卡都没收了,等我玩够了再还给你们,这样你们就不会死锁了。 不过Jerry仔细端详了这些一零后们喜欢玩的奥特曼卡片,发现毫无吸引我之处。我还是更喜欢欣赏和收藏这些反映祖国传统文化的水浒传人物卡片。 言归正传,在使用ABAP答这道面试题之前,我们先看看如何用Java编写一个会出现死锁的程序。 不到40行代码就完成任务。为了便于ABAP从业人员理解,没有使用Java里的Lambda表达式,否则代码可以更短。...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7,8上快速安装Gitea,搭建Git服务器
- 设置Eclipse缩进为4个空格,增强代码规范
- SpringBoot2全家桶,快速入门学习开发网站教程
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Red5直播服务器,属于Java语言的直播服务器
- CentOS8安装Docker,最新的服务器搭配容器使用
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7