Stream流之groupingBy分组详解 (java1.8 新特性)

哈喽,小伙伴们,最近开在工作中,用到了特别省事的Stream流,但是对于groupingBy分组不常用,特来记录一下,ok~  上干货。

Collectors.groupingBy() 分组之统计每个分组的count

(使用java8 stream groupingBy操作,按城市分组list统计count)

List<Device> alarmRecordList = new ArrayList<>();
        Device device_01 = new Device();
        device_01.setUseTime(15);
        device_01.setName("水表");
        Device device_02 = new Device();
        device_02.setUseTime(16);
        device_02.setName("水表");
        Device device_03 = new Device();
        device_03.setUseTime(17);
        device_03.setName("电表");
        Device device_04 = new Device();
        device_04.setUseTime(18);
        device_04.setName("温湿度传感器");
        // 添加设备
        alarmRecordList.add(device_01);
        alarmRecordList.add(device_02);
        alarmRecordList.add(device_03);
        alarmRecordList.add(device_04);
        // 对设备名称进行分组
        Map<String, Long> groupMap = alarmRecordList.stream().collect(Collectors.groupingBy(Device::getName, Collectors.counting()));
        System.out.println(groupMap);

结果运行图:

结果就很清晰的能看到对我们的结果数据的分组以及聚合。

Collectors.groupingBy() 分组之统计分组平均值

(使用java8 stream groupingBy操作,按城市分组list并计算分组年龄平均值)

        List<Device> alarmRecordList = new ArrayList<>();
        Device device_01 = new Device();
        device_01.setUseTime(15);
        device_01.setName("水表");
        Device device_02 = new Device();
        device_02.setUseTime(16);
        device_02.setName("水表");
        Device device_03 = new Device();
        device_03.setUseTime(17);
        device_03.setName("电表");
        Device device_04 = new Device();
        device_04.setUseTime(18);
        device_04.setName("温湿度传感器");
        // 添加设备
        alarmRecordList.add(device_01);
        alarmRecordList.add(device_02);
        alarmRecordList.add(device_03);
        alarmRecordList.add(device_04);
        // 对设备名称进行分组求平均值
        Map<String, Double> collect = alarmRecordList.stream()
                .collect(Collectors.groupingBy(Device::getName, Collectors.averagingInt(Device::getUseTime)));
        System.out.println(collect);

结果运行图:

仔细观察集合中的数据,然后对比结果。

Collectors.groupingBy() 分组之转换分组结果List -> List

(使用java8 stream groupingBy操作,按城市分组list,将List转化为name的List)

        List<Device> alarmRecordList = new ArrayList<>();
        Device device_01 = new Device();
        device_01.setUseTime(15);
        device_01.setName("水表");
        Device device_02 = new Device();
        device_02.setUseTime(16);
        device_02.setName("水表");
        Device device_03 = new Device();
        device_03.setUseTime(17);
        device_03.setName("电表");
        Device device_04 = new Device();
        device_04.setUseTime(18);
        device_04.setName("温湿度传感器");
        // 添加设备
        alarmRecordList.add(device_01);
        alarmRecordList.add(device_02);
        alarmRecordList.add(device_03);
        alarmRecordList.add(device_04);
        // 对设备名称进行分组结果转换为List
        Map<String, List<String>> collect = alarmRecordList.stream()
                .collect(Collectors.groupingBy(Device::getName, Collectors.mapping(Device::getName, Collectors.toList())));
        collect.forEach((k,v) ->{
            System.out.println(k+"=="+v);
        });

运行结果图:

Collectors.groupingBy() 分组之转换分组结果List -> Set

(使用java8 stream groupingBy操作,按城市分组list,将List转化为name的Set)

        List<Device> alarmRecordList = new ArrayList<>();
        Device device_01 = new Device();
        device_01.setUseTime(15);
        device_01.setName("水表");
        Device device_02 = new Device();
        device_02.setUseTime(16);
        device_02.setName("水表");
        Device device_03 = new Device();
        device_03.setUseTime(17);
        device_03.setName("电表");
        Device device_04 = new Device();
        device_04.setUseTime(18);
        device_04.setName("温湿度传感器");
        // 添加设备
        alarmRecordList.add(device_01);
        alarmRecordList.add(device_02);
        alarmRecordList.add(device_03);
        alarmRecordList.add(device_04);
        // 对设备名称进行分组将List转化为name的Set
        Map<String, Set<String>> collect = alarmRecordList.stream()
                .collect(Collectors.groupingBy(Device::getName, Collectors.mapping(Device::getName, Collectors.toSet())));
        collect.forEach((k,v) ->{
            System.out.println(k+"=="+v);
        });

运行结果图:

结果图虽然和转换成list没有区别,但是仅仅是结果,转换的集合是有所不同的。

Collectors.groupingBy() 分组之使用对象分组List

(使用java8 stream groupingBy操作,通过Object对象的成员分组List)

        List<Device> alarmRecordList = new ArrayList<>();
        Device device_01 = new Device();
        device_01.setUseTime(15);
        device_01.setName("水表");
        Device device_02 = new Device();
        device_02.setUseTime(16);
        device_02.setName("水表");
        Device device_03 = new Device();
        device_03.setUseTime(17);
        device_03.setName("电表");
        Device device_04 = new Device();
        device_04.setUseTime(18);
        device_04.setName("温湿度传感器");
        // 添加设备
        alarmRecordList.add(device_01);
        alarmRecordList.add(device_02);
        alarmRecordList.add(device_03);
        alarmRecordList.add(device_04);
        // 对设备名称进行分组通过Object对象的成员分组List
        Map<Manage, List<Device>> collect = alarmRecordList.stream()
                .collect(Collectors.groupingBy(item -> {
                    return new Manage(item.getName());
                }));

        collect.forEach((k,v) ->{
            System.out.println(k+"=="+v);
        });

自定义Distinct对结果去重

(使用java8 stream groupingBy操作, 基于city 和name 实现多次分组)

     /**
	 * 自定义重复key 规则
	 * @param keyExtractor
	 * @return
	 */
	private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
		Set<Object> seen = ConcurrentHashMap.newKeySet();
		return t -> seen.add(keyExtractor.apply(t));
	}
List<Employee> list = employees.stream().filter(distinctByKey(Employee :: getCity))
				.collect(Collectors.toList());;
 
		list.stream().forEach(item->{
			System.out.println("city = " + item.getCity());
		});

希望对大家有帮助 下期再见呦~

本文参考:Java8 Stream 之groupingBy 分组讲解_在奋斗的大道的博客-CSDN博客

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值