java stream流之groupby的用法

简单分组
  • 按照年龄对 Person 对象进行分组:
  1. 代码示例
import java.util.*;
import java.util.stream.Collectors;

public class SimpleGrouping {
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
            new Person("Alice", 30),
            new Person("Bob", 25),
            new Person("Charlie", 30),
            new Person("David", 25),
            new Person("Eve", 35)
        );

		// 通过对age字段进行分组,得到相同年龄的people对象list
        Map<Integer, List<Person>> groupedByAge = people.stream()
            .collect(Collectors.groupingBy(Person::getAge));

        groupedByAge.forEach((age, personList) -> {
            System.out.println("Age: " + age);
            personList.forEach(person -> System.out.println(person));
        });
    }
}

  1. 输出结果
Age: 25
Person{name='Bob', age=25}
Person{name='David', age=25}
Age: 30
Person{name='Alice', age=30}
Person{name='Charlie', age=30}
Age: 35
Person{name='Eve', age=35}

分组并统计

  • 按年龄分组并统计每个年龄段的人数:
  1. 代码示例
import java.util.*;
import java.util.stream.Collectors;

public class GroupingAndCounting {
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
            new Person("Alice", 30),
            new Person("Bob", 25),
            new Person("Charlie", 30),
            new Person("David", 25),
            new Person("Eve", 35)
        );
		// 通过对年龄字段进行分组,然后对分组后的数据进行统计
        Map<Integer, Long> countByAge = people.stream()
            .collect(Collectors.groupingBy(
                Person::getAge,
                Collectors.counting()
            ));

        countByAge.forEach((age, count) -> {
            System.out.println("Age: " + age + ", Count: " + count);
        });
    }
}

  1. 数据结果
Age: 25, Count: 2
Age: 30, Count: 2
Age: 35, Count: 1


分组并进行数据转换

  • 按年龄分组,并将每组中的 Person 对象转换为姓名列表:
  1. 代码示例
import java.util.*;
import java.util.stream.Collectors;

public class GroupingAndMapping {
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
            new Person("Alice", 30),
            new Person("Bob", 25),
            new Person("Charlie", 30),
            new Person("David", 25),
            new Person("Eve", 35)
        );

        Map<Integer, List<String>> namesByAge = people.stream()
            .collect(Collectors.groupingBy(
                Person::getAge,
                Collectors.mapping(Person::getName, Collectors.toList())
            ));

 // Collectors.groupingBy(param1,param2) param1:要求返回一个对象这就意味着我们可以在这里再次创建对象;
 // Collectors.mapping(Person::getName, Collectors.toList()) 同理:Person::getName 也可以替换为 p->new People1(p.getName,p.getAge)
        namesByAge.forEach((age, names) -> {
            System.out.println("Age: " + age + ", Names: " + names);
        });
    }
}


  1. 输出结果
Age: 25, Names: [Bob, David]
Age: 30, Names: [Alice, Charlie]
Age: 35, Names: [Eve]


多级分组

  • 先按年龄分组,再按姓名的首字母进行分组:
  1. 示例代码

import java.util.*;
import java.util.stream.Collectors;

public class MultiLevelGrouping {
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
            new Person("Alice", 30),
            new Person("Bob", 25),
            new Person("Charlie", 30),
            new Person("David", 25),
            new Person("Eve", 35)
        );

        Map<Integer, Map<Character, List<Person>>> multiLevelGrouping = people.stream()
            .collect(Collectors.groupingBy(
                Person::getAge,
                Collectors.groupingBy(person -> person.getName().charAt(0))
            ));

        multiLevelGrouping.forEach((age, group) -> {
            System.out.println("Age: " + age);
            group.forEach((initial, persons) -> {
                System.out.println("  Initial: " + initial);
                persons.forEach(person -> System.out.println("    " + person));
            });
        });
    }
}

  1. 输出结果
Age: 25
  Initial: B
    Person{name='Bob', age=25}
  Initial: D
    Person{name='David', age=25}
Age: 30
  Initial: A
    Person{name='Alice', age=30}
  Initial: C
    Person{name='Charlie', age=30}
Age: 35
  Initial: E
    Person{name='Eve', age=35}


分组并收集到不同的集合

  • 按年龄分组,并将每组中的 Person 对象收集到 Set 中:
  1. 代码示例
import java.util.*;
import java.util.stream.Collectors;

public class GroupingToSet {
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
            new Person("Alice", 30),
            new Person("Bob", 25),
            new Person("Charlie", 30),
            new Person("David", 25),
            new Person("Eve", 35)
        );

        Map<Integer, Set<Person>> groupedByAgeToSet = people.stream()
            .collect(Collectors.groupingBy(
                Person::getAge,
                Collectors.toSet()
            ));

        groupedByAgeToSet.forEach((age, personSet) -> {
            System.out.println("Age: " + age);
            personSet.forEach(person -> System.out.println(person));
        });
    }
}


  1. 输出结果
Age: 25
Person{name='Bob', age=25}
Person{name='David', age=25}
Age: 30
Person{name='Alice', age=30}
Person{name='Charlie', age=30}
Age: 35
Person{name='Eve', age=35}


自定义收集器

  • 按年龄分组,并计算每组的平均年龄:
  1. 代码示例
import java.util.*;
import java.util.stream.Collectors;

public class GroupingWithCustomCollector {
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
            new Person("Alice", 30),
            new Person("Bob", 25),
            new Person("Charlie", 30),
            new Person("David", 25),
            new Person("Eve", 35)
        );

        Map<Integer, Double> averageAgeByGroup = people.stream()
            .collect(Collectors.groupingBy(
                Person::getAge,
                Collectors.averagingInt(Person::getAge)
            ));

        averageAgeByGroup.forEach((age, avgAge) -> {
            System.out.println("Age: " + age + ", Average Age: " + avgAge);
        });
    }
}

  1. 输出结果
Age: 25, Average Age: 25.0
Age: 30, Average Age: 30.0
Age: 35, Average Age: 35.0


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值