Java中Collectors.toMap()的基本使用方法和使用场景

Posted 拄杖忙学轻声码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中Collectors.toMap()的基本使用方法和使用场景相关的知识,希望对你有一定的参考价值。

介绍:
1、Collectors.toMap()是Java8引入的流特性,可以把集合转换为Map集合,转换对象中的key不可重复,重复会报错
2、如果key重复,可以使用合并函数来取其默认值,避免报错

使用:

一、key不重复场景

1、数据集合准备

List<PersonDto> objects = ListUtil.toList(
                new PersonDto(1L, "张三", "北京", 25),
                new PersonDto(2L, "李四", "上海", 26),
                new PersonDto(3L, "王五", "广州", 28),
                new PersonDto(4L, "赵六", "深圳", 32),
                new PersonDto(5L, "孙七", "香港", 35)
        );

2、List转Map,id作为key,name作为value,id不可重复

Map<Long, String> collect = objects.stream().collect(Collectors.toMap(PersonDto::getId, PersonDto::getUserName));
System.out.println("collect = " + collect);

输出如下:

collect = 1=张三, 2=李四, 3=王五, 4=赵六, 5=孙七

3、List转Map,id作为key,元素对象作为value,id不可重复

Map<Long, PersonDto> collect1 = objects.stream().collect(Collectors.toMap(PersonDto::getId, o -> o));
System.out.println("collect1 = " + collect1);

输出如下:

collect1 = 
	1=PersonDto(id=1, userName=张三, email=null, address=北京, age=25), 
	2=PersonDto(id=2, userName=李四, email=null, address=上海, age=26), 
	3=PersonDto(id=3, userName=王五, email=null, address=广州, age=28), 
	4=PersonDto(id=4, userName=赵六, email=null, address=深圳, age=32), 
	5=PersonDto(id=5, userName=孙七, email=null, address=香港, age=35)

二、key重复场景

1、数据集合准备

List<PersonDto> objects = ListUtil.toList(
                new PersonDto(1L, "张三", "北京", 25),
                new PersonDto(2L, "李四", "上海", 26),
                new PersonDto(3L, "王五1", "上海", 26),
                new PersonDto(3L, "王五2", "广州", 28),
                new PersonDto(4L, "赵六", "深圳", 32),
                new PersonDto(5L, "孙七", "香港", 35),
                new PersonDto(5L, "周八", "香港", 36),
                new PersonDto(5L, "吴九", "新加坡", 37)
        );

2、List转Map,id作为key,name作为value,如果Id重复取第一个name

Map<Long, String> collect = objects.stream().collect(Collectors.toMap(PersonDto::getId, PersonDto::getUserName, (o1, o2) -> o1));
System.out.println("collect = " + collect);

输出如下:

collect = 1=张三, 2=李四, 3=王五1, 4=赵六, 5=孙七

3、List转Map,id作为key,元素对象作为value,如果Id重复取第一个元素

Map<Long, PersonDto> collect1 = objects.stream().collect(Collectors.toMap(PersonDto::getId, o -> o, (o1, o2) -> o1));
System.out.println("collect1 = " + collect1);

输出如下:

collect1 = 
	1=PersonDto(id=1, userName=张三, email=null, address=北京, age=25), 
	2=PersonDto(id=2, userName=李四, email=null, address=上海, age=26), 
	3=PersonDto(id=3, userName=王五1, email=null, address=上海, age=26), 
	4=PersonDto(id=4, userName=赵六, email=null, address=深圳, age=32), 
	5=PersonDto(id=5, userName=孙七, email=null, address=香港, age=35)

4、List转Map,id作为key,name作为value,如果Id重复取最后一个name

Map<Long, String> collect2 = objects.stream().collect(Collectors.toMap(PersonDto::getId, PersonDto::getUserName, (o1, o2) -> o2));
System.out.println("collect2 = " + collect2);

输出如下:

collect2 = 1=张三, 2=李四, 3=王五2, 4=赵六, 5=吴九

小结:
1、Java中Collectors.toMap()可以把List集合转换为Map集合,key不允许重复
2、转换为Map集合的前提是key不能重复,如果重复需要使用合并函数取默认值,否则会报错
3、合并函数有两个参数,第一个参数是重复数据中的第一个元素,第二个参数是重复数据中的最后一个元素,可以用来返回默认值
4、使用合并函数可以配合排序函数,根据排序规则正序、倒叙,取每组重复数据中最近或最远的一条数据,用来处理适当的业务

java8的stream中Collectors.toMap空指针问题

在工作中遇到了一个ListMap的时候的一个NullPointException.

情形很简单,问题出在Collectors.toMap,当key值冲突的时候理论上会按照我们的代码来替换value,但是这里有个小坑

list.stream().collect(Collectors.toMap(it -> it.getCategoryId(), it -> it.getCategoryImage() ,(k1,k2) -> k2));

可以看到mapkey值冲突merge的时候会要求新的value不能为null.
这意味着,只要传入了(k1,k2) -> k2处理key冲突的function,那么当value里存在Null的时候必然会抛NullPointException

以上是关于Java中Collectors.toMap()的基本使用方法和使用场景的主要内容,如果未能解决你的问题,请参考以下文章

Collectors.toMap空指针异常

Java8 中 List 转 Map(Collectors.toMap) 使用技巧

Java8 中 List 转 Map(Collectors.toMap) 使用技巧

Java8 中 List 转 Map(Collectors.toMap) 使用技巧

JAVA集合05_Collection.toMap()应用三个重载方法解决重复key问题

Collectors.toMap() keyMapper——更简洁的表达方式?