java8 Stream 列表分组、分区,按列表元素的某个属性分组

简单条件分组

  • 无明确条件指定,对应属性值的类别有多少个,分组就有多少个
Map<String, List<Student>> collect = studentList.stream().collect(Collectors.groupingBy(Student::getName));

这里我们使用方法引用(类名::实例方法名)替代lambda表达式(s -> s.getName())的方式来指定classifier分类器,使集合按Student的name来分组。
注意到分组后的返回类型是Map<String, List>,结果集中会将name作为key,对应的Student集合作为value返回。

复杂条件分组

  • 传入lambda表达式,根据属性学生成绩的不同值等级来分组,有明确的条件指定

        Map<String, List<Student>> collect = studentList.stream().collect(Collectors.groupingBy(student->{
            if (student.getScore() >= 90) {
                return "优秀";
            } else if (student.getScore() >= 80) {
                return "良好";
            } else {
                return "一般";
            }
        }));

分组之后,再用收集器统计

如果按name分组后,想求出每组学生的数量,就需要借助groupingBy另一个重载的方法

public static Collector groupingBy(Function<? super T, ? extends K> classifier,Collector<? super T, A, D> downstream){
    //...
}

第二个参数downstream还是一个收集器Collector对象,也就是说我们可以先将classifier作为key进行分组,然后将分组后的结果交给downstream收集器再进行处理

//按name分组 得出每组的学生数量 使用重载的groupingBy方法,第二个参数是分组后的操作
Map<String, Long> collect1 = studentList.stream()
								.collect(Collectors.groupingBy(Student::getName, Collectors.counting()));
//按名字分组,求出每个学生平均分
Map<String, Double> collect2 = studentList.stream()
		.collect(Collectors.groupingBy(Student::getName, Collectors.averagingDouble(Student::getScore)));

分区

我们现在再加一个需求,分别统计一下及格和不及格的学生(分数是否>=60)
这时候符合Stream分区的概念了,Stream分区会将集合中的元素按条件分成两部分结果,key是Boolean类型,value是结果集,满足条件的key是true

Map<Boolean, List<Student>> collect3 = students.stream()
							.collect(Collectors.partitioningBy(student -> student.getScore() >= 60));
System.out.println(collect3.get(true));//输出及格的Student
System.out.println(collect3.get(false));//输出不及格的Student

参考链接

Java8-10-Stream分组与分区详解
JDK1.8-Stream中常用的API(流操作)

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 8中的Stream API提供了一种方便的方法来对集合进行操作。其中之一是分组和提取属性。下面是一个例子,假设我们有一个Person类,其中包含姓名和年龄两个属性。我们想要将这些人按照年龄分组,并提取他们的姓名。可以使用Stream的groupingBy和mapping方法来实现这个目标。代码如下: ``` public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } } public class StreamTest { public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Alice", 20), new Person("Bob", 30), new Person("Charlie", 20), new Person("David", 25) ); Map<Integer, List<String>> result = people.stream() .collect(Collectors.groupingBy(Person::getAge, Collectors.mapping(Person::getName, Collectors.toList()))); System.out.println(result); } } ``` 在这个例子中,我们首先创建了一个Person类,然后创建了一个包含四个人的列表。接下来,我们使用Stream的groupingBy方法按照年龄对人进行分组。在这个方法中,我们使用Person::getAge作为分组依据。然后,我们使用mapping方法来提取每个人的姓名,并将结果收集到一个列表中。最后,我们将结果存储在一个Map中,并将年龄作为键,姓名列表作为值。输出结果为:{20=[Alice, Charlie], 25=[David], 30=[Bob]}。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值