Java Stream流 List< T >转换Map方法汇总合集

List< T > -> Map< T, T >


List< Integer> -> Map< Integer,Integer>
代码示例(本示例是存在重复key,并且会以首个出现的 key 去覆盖后面出现的冲突 key):

     @Test
    public void testList2() {
        List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 4, 5, 6, 7, 8,1);
        Map<Integer, Integer> collect = list.stream().collect(Collectors.toMap(k -> k, v -> v, (k1, k2) -> k1));
        System.out.println("collect:" + collect);
    }

输出的结果:

{"1:1","2:2","3:3","4:4","5:5","6:6","7:7","8:8"}


toMap()无重复key


示例一
List泛型为 Student 对象,示例需要将name属性作为 key,age 属性作为value;

    @Test
    public void testList2() {
        List<Student> list = Lists.newArrayList(
                new Student("小张", 17, DateUtil.parse("2006-10-03 15:18:56"), 11),
                new Student("小李", 15, DateUtil.parse("2008-03-19 02:18:56"), 5),
                new Student("小王", 16, DateUtil.parse("2007-02-21 22:18:56"), 29));
        Map<String, Integer> collect = list.stream().collect(Collectors.toMap(Student::getName, Student::getAge));
        System.out.println(JSONObject.toJSONString(collect));
    }

输出结果: 

{"小张":11","小李":5","小王":29"}


示例二
List泛型为 Student 对象,示例需要将name属性作为 key, Student 对象作为value;

@Test
    public void testList2() {
        List<Student> list = Lists.newArrayList(
                new Student("小张", 17, DateUtil.parse("2006-10-03 15:18:56"), 11),
                new Student("小李", 15, DateUtil.parse("2008-03-19 02:18:56"), 5),
                new Student("小王", 16, DateUtil.parse("2007-02-21 22:18:56"), 29));
        Map<String, Student> collect = list.stream().collect(Collectors.toMap(Student::getName, student -> student));
        System.out.println(JSONObject.toJSONString(collect));
    }


运行结果:

toMap()有重复key


当存在重复 key 时,编译器会报错:java.lang.IllegalStateException: Duplicate key xxxx;
出现这种情况就需要在 toMap() 方法中指定 key 来避免冲突;

示例一
解决办法:使用第一个key 覆盖第二个key;

    @Test
    public void testList2() {
        List<Student> list = Lists.newArrayList(
                new Student("小张", 17, DateUtil.parse("2006-10-03 15:18:56"), 11),
                new Student("小李", 15, DateUtil.parse("2008-03-19 02:18:56"), 5),
                new Student("小李", 15, DateUtil.parse("2008-03-19 02:18:56"), 2),
                new Student("小王", 16, DateUtil.parse("2007-02-21 22:18:56"), 29));
        Map<String, Student> collect = list.stream().collect(Collectors.toMap(Student::getName, student -> student, (key1, key2) -> key1));
        System.out.println(JSONObject.toJSONString(collect));
    }



运行结果(保留了 “num”:11 的对象):

示例二
解决办法:使用第二个key 覆盖第一个key;

    @Test
    public void testList2() {
        List<Student> list = Lists.newArrayList(
                new Student("小张", 17, DateUtil.parse("2006-10-03 15:18:56"), 11),
                new Student("小李", 15, DateUtil.parse("2008-03-19 02:18:56"), 5),
                new Student("小李", 15, DateUtil.parse("2008-03-19 02:18:56"), 2),
                new Student("小王", 16, DateUtil.parse("2007-02-21 22:18:56"), 29));
        Map<String, Student> collect = list.stream().collect(Collectors.toMap(Student::getName, student -> student, (key1, key2) -> key2));
        System.out.println(JSONObject.toJSONString(collect));
    }



运行结果(保留了 “num”:2 的对象):

toMap()空指针异常


当 value 为空时,使用 toMap() 方法进行转换,编译器会抛出 java.lang.NullPointerException;

   @Test
    public void testList2() {
        List<Student> list = Lists.newArrayList(
                new Student("小张", 17, DateUtil.parse("2006-10-03 15:18:56"), 11),
                new Student("小李", 15, DateUtil.parse("2008-03-19 02:18:56"), 5),
                new Student("小王", 16, DateUtil.parse("2007-02-21 22:18:56"), 29),
                new Student("小田", null, DateUtil.parse("2007-02-21 22:18:56"), null));
        Map<String, Integer> collect = list.stream().collect(Collectors.toMap(Student::getName, Student::getAge));
        System.out.println(JSONObject.toJSONString(collect));
    }


运行结果:

解决办法一
转换时增加判断,如果是null,则设置默认值;

    @Test
    public void testList2() {
        List<Student> list = Lists.newArrayList(
                new Student("小张", 17, DateUtil.parse("2006-10-03 15:18:56"), 11),
                new Student("小李", 15, DateUtil.parse("2008-03-19 02:18:56"), 5),
                new Student("小王", 16, DateUtil.parse("2007-02-21 22:18:56"), 29),
                new Student("小田", null, DateUtil.parse("2007-02-21 22:18:56"), null));
        Map<String, Integer> collect = list.stream().collect(Collectors.toMap(Student::getName, s -> s.getAge() == null ? -1 : s.getAge()));
        System.out.println(JSONObject.toJSONString(collect));
    }


运行结果:

解决办法二
使用 Optional< T > 对值进行包装

(和方式一大同小异,就是换了个写法):

    @Test
    public void testList2() {
        List<Student> list = Lists.newArrayList(
                new Student("小张", 17, DateUtil.parse("2006-10-03 15:18:56"), 11),
                new Student("小李", 15, DateUtil.parse("2008-03-19 02:18:56"), 5),
                new Student("小王", 16, DateUtil.parse("2007-02-21 22:18:56"), 29),
                new Student("小田", null, DateUtil.parse("2007-02-21 22:18:56"), null));
        Map<String, Integer> collect = list.stream().collect(Collectors.toMap(Student::getName,  s -> Optional.ofNullable(s.getAge()).orElse(-1)));
        System.out.println("Optional:"+JSONObject.toJSONString(collect));
    }


运行结果:

解决办法三
使用collect(Supplier< R > supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) 来构建,可允许null值的出现:

    @Test
    public void testList2() {
        List<Student> list = Lists.newArrayList(
                new Student("小张", 17, DateUtil.parse("2006-10-03 15:18:56"), 11),
                new Student("小李", 15, DateUtil.parse("2008-03-19 02:18:56"), 5),
                new Student("小王", 16, DateUtil.parse("2007-02-21 22:18:56"), 29),
                new Student(null, 12, DateUtil.parse("2007-02-21 22:18:56"), null));
        HashMap<Integer, String> collect = list.stream().collect(HashMap::new, (obj, v) -> obj.put(v.getAge(), v.getName()), HashMap::putAll);
        System.out.println("collect:" + collect);
    }


运行结果:

List< T > -> Map< T, List< T > >

groupingBy()
直接根据一个字段或者属性分组也可以直接用 groupingBy() 方法:

 

   @Test
    public void testList2() {
        List<Student> list = Lists.newArrayList(
                new Student("小张", 17, DateUtil.parse("2006-10-03 15:18:56"), 11),
                new Student("小李", 15, DateUtil.parse("2008-03-19 02:18:56"), 5),
                new Student("小李", 15, DateUtil.parse("2008-03-19 02:18:56"), 2),
                new Student("小王", 16, DateUtil.parse("2007-02-21 22:18:56"), 29));
        Map<String, List<Student>> collect = list.stream().collect(Collectors.groupingBy(Student::getName));
        System.out.println(JSONObject.toJSONString(collect));
    }


运行结果:

partitioningBy()
partitioningBy() 可以理解为特殊的 groupingBy() ,key 值为 Boolean类型:

    @Test
    public void testList2() {
        List<Student> list = Lists.newArrayList(
                new Student("小张", 17, DateUtil.parse("2006-10-03 15:18:56"), 11),
                new Student("小李", 15, DateUtil.parse("2008-03-19 02:18:56"), 5),
                new Student("小李", 15, DateUtil.parse("2008-03-19 02:18:56"), 2),
                new Student("小王", 16, DateUtil.parse("2007-02-21 22:18:56"), 29));
        Map<Boolean, List<Student>> collect = list.stream().collect(Collectors.partitioningBy(s -> s.getNum() >= 5));
        System.out.println(JSONObject.toJSONString(collect));
    }


运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值