Java8 中 List 转 Map(Collectors.toMap)

在实际项目中我们经常会用到 List 转 Map 操作,在过去我们可能使用的是 for 循环遍历的方式。举个例子:

先定义类:

// 简单对象 
@Accessors(chain = true) // 链式方法 
@lombok.Data
class User {
    private String id;
    private String name;
}

然后有这样一个 List:
List<User> userList = Lists.newArrayList(
        new User().setId("A").setName("张三"),
        new User().setId("B").setName("李四"),
        new User().setId("C").setName("王五")
);

我们希望转成 Map 的格式为:
A-> 张三 
B-> 李四 
C-> 王五 

过去的做法(循环):
Map<String, String> map = new HashMap<>();
for (User user : userList) {
    map.put(user.getId(), user.getName());
}

使用 Java8 特性

以上述例子为例,我们可以一句话搞定:
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,
        BinaryOperator<U> mergeFunction);
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,
        BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier);

参数含义分别是:
keyMapper:Key 的映射函数
valueMapper:Value 的映射函数
mergeFunction:当 Key 冲突时,调用的合并方法
mapSupplier:Map 构造器,在需要返回特定的 Map 时使用

上面的例子,如果 List 中 userId 有相同的,使用上面的写法会抛异常:

List<User> 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 张三 

这时就需要调用第二个重载方法,传入合并函数,如:

userList.stream().collect(Collectors.toMap(User::getId, User::getName, (n1, n2) -> n1 + n2));

// 输出结果:
A-> 张三李四 
C-> 王五 

第四个参数(mapSupplier)用于自定义返回 Map 类型,比如我们希望返回的 Map 是根据 Key 排序的,可以使用如下写法:

List<User> 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-> 王五 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值