济南地产行业网站开发,地方网站发展,公司旅游视频网站模板,甜品网页设计图片Java8 中 List 转 Map(Collectors.toMap) 使用技巧
在实际项目中我们经常会用到 List 转 Map 操作#xff0c;在过去我们可能使用的是 for 循环遍历的方式。举个例子#xff1a;
先定义类#xff1a;
// 简单对象
Accessors(chain true) // 链式方法
lombok.Data
clas…Java8 中 List 转 Map(Collectors.toMap) 使用技巧
在实际项目中我们经常会用到 List 转 Map 操作在过去我们可能使用的是 for 循环遍历的方式。举个例子
先定义类
// 简单对象
Accessors(chain true) // 链式方法
lombok.Data
class User {private String id;private String name;
}然后有这样一个 List
ListUser userList Lists.newArrayList(new User().setId(A).setName(张三),new User().setId(B).setName(李四),new User().setId(C).setName(王五)
);我们希望转成 Map 的格式为
A- 张三
B- 李四
C- 王五 过去的做法循环
MapString, String map new HashMap();
for (User user : userList) {map.put(user.getId(), user.getName());
}使用 Java8 特性
Java8 中新增了 Stream 特性使得我们在处理集合操作时更方便了。
以上述例子为例我们可以一句话搞定
userList.stream().collect(Collectors.toMap(User::getId, User::getName));当然如果希望得到 Map 的 value 为对象本身时可以这样写
userList.stream().collect(Collectors.toMap(User::getId, t - t));或
userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));关于 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,BinaryOperatorU mergeFunction);
toMap(Function? super T, ? extends K keyMapper, Function? super T, ? extends U valueMapper,BinaryOperatorU mergeFunction, SupplierM mapSupplier);
参数含义分别是
keyMapperKey 的映射函数valueMapperValue 的映射函数mergeFunction当 Key 冲突时调用的合并方法mapSupplierMap 构造器在需要返回特定的 Map 时使用
还是用上面的例子如果 List 中 userId 有相同的使用上面的写法会抛异常
ListUser userList Lists.newArrayList(new User().setId(A).setName(张三),new User().setId(A).setName(李四), // Key 相同 new User().setId(C).setName(王五)
);
userList.stream().collect(Collectors.toMap(User::getId, User::getName));// 异常
java.lang.IllegalStateException: Duplicate key 张三 at java.util.stream.Collectors.lambda$throwingMerger$114(Collectors.java:133)at java.util.HashMap.merge(HashMap.java:1245)at java.util.stream.Collectors.lambda$toMap$172(Collectors.java:1320)at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)at Test.toMap(Test.java:17)...这时就需要调用第二个重载方法传入合并函数如
userList.stream().collect(Collectors.toMap(User::getId, User::getName, (n1, n2) - n1 n2));// 输出结果
A- 张三李四
C- 王五 第四个参数mapSupplier用于自定义返回 Map 类型比如我们希望返回的 Map 是根据 Key 排序的可以使用如下写法
ListUser userList Lists.newArrayList(new User().setId(B).setName(张三),new User().setId(A).setName(李四),new User().setId(C).setName(王五)
);
userList.stream().collect(Collectors.toMap(User::getId, User::getName, (n1, n2) - n1, TreeMap::new)
);// 输出结果
A- 李四
B- 张三
C- 王五