1.引入:
在之前的项目中如果出现List转Map的操作,我们一般都是通过遍历List中的每个元素,再将遍历到的元素设置到Map中去,如下所示:
import java.util.*;
@Data
class User{
public String id;
public String name;
}
public class Main {
public static void main(String[] args) {
List<User> users = new ArrayList<>();
User user1 = new User();
user1.setId("1");
user1.setName("张三");
User user2 = new User();
user2.setId("2");
user2.setName("李四");
users.add(user1);
users.add(user2);
Map<String, String> map = new HashMap<>();
for(User u : users){
map.put(u.id, u.name);
}
System.out.println(map);
}
}
运行结果:
2.使用Java8的新特性
上述例子可以改变为这样一句话的代码:
Map<String, String> map = users.stream().collect(Collectors.toMap(User::getId, User::getName));
System.out.println(map);
运行结果依然是正确的:
.stream(): 把一个数据源,可以是集合、数组等,转化成流。
.collect(): 对流的元素执行可变的归约操作。可变归约操作处理流元素,然后将其累积到可变结果容器中,处理完元素后,合并功能将合并所有结果容器以创建结果。
3.Collectors.toMap 方法
Collectors.toMap()方法有两个重载方法:
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper);
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction);
参数含义分别是:
- keyMapper:Key 的映射函数
- valueMapper:Value 的映射函数
- mergeFunction:当 Key 冲突时,调用的合并方法
如上边的例子,如果我们存在重复的key的话就会报错,代码如下:
List<User> users = Arrays.asList(
new User().setId("1").setName("张三"),
new User().setId("1").setName("李四")
);
Map<String, String> map = users.stream().collect(Collectors.toMap(User::getId, User::getName));
会报错:
此时我们就需要加上第三个参数(mergeFunction)作为合并的方法,使用Lambda表达式进行value的合并,如下将两个value的值进行拼接:
Map<String, String> map = users.stream().collect(Collectors.toMap(User::getId, User::getName, (a, b) -> a + b));