Stream流实现list转Map,相同字段对应的不同字段汇集成list

背景

    最近在某大厂线下面试二面的时候,简历里写的"熟练掌握JDK8新特性,熟练使用Stream流、Lambda表达式等"给自己埋了个坑,面试官拿笔在Stream流上给圈了一下,并抛出了一个问题,假设现在我从数据库里查出了一个List集合,也就是多行记录,他们的A字段都是一样的,B字段不同,如何实现将这个List用Stream流转成Map,以A字段作为key,B字段作为Value,相同A字段对应的不同B字段放到一个list里,也就是实现List=> Map<A,List<B字段>>的转换
    这问题我熟啊,平常开发也经常用,不用Stream流用for循环也就一次遍历,可stream流偏偏我忘了,当时只记得是在筛选的时候,用了个啥groupBy分组,但是分组方法怎么写我忘了,给面试官留下不好印象了哎好可惜…于是乎我决定痛定思痛,好好记录一下。

解决

正常普通实现

    首先正常用for循环也就一次遍历,假设现在list中的元素就是一个包含两元素的一维数组,其中第一个元素对应问题中的A字段,第二个元素对应问题中的第二个字段。
    List为[ [1,2], [1,3], [2,1], [2,2], [2,3] ],那么代码就如下所示:

		Map<Integer,List<Integer>> map = new HashMap<>();
        for(int[] arr:list){
            map.computeIfAbsent(arr[0], key -> new ArrayList<>()).add(arr[1]);
        }
        //结果为:1=>[2, 3]    2=>[1, 2, 3]

Stream流实现

    我去翻了翻自己以前写的代码,原来是Collectors.groupingBy()方法,然后用Collectors.mapping第二个元素映射成List集合,代入这个示例下的代码如下所示:

		Map<Integer, List<Integer>> map = list.stream()
        .collect(Collectors.groupingBy(
            arr -> arr[0],
            Collectors.mapping(arr -> arr[1], Collectors.toList())
        ));

    仔细想想,这方法是我让chatGpt帮忙写的,可读性差,还要记这方法名,难怪自己线下写不出,然后老老实实去巩固了下toMap的基础用法,以后还是踏踏实实这么写把,可读性好,易理解,也通用,下次面试也不至于不会写!!

		Map<Integer,List<Integer>> streamMap = list.stream().collect(Collectors.toMap(
           arr->arr[0],
           arr->new ArrayList<>(Arrays.asList(arr[1])),
           (oldList,newList)->{
               newList.addAll(oldList);
               return newList;
           }));

    直接使用toMap()方法,key指定为arr[0],value指定为一个初始值为arr[1]的List集合,当key相同时,执行第三个参数,也是一个方法,传入旧value,新value也就是上一个key对应的list和当前key对应的list,方法内执行的操作就是合并两集合,这样不管今后有什么操作,都不用拘泥于去找对应的方法api名字了

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值