项目开发中经常需要将 List 转 Map 的操作,可以使用 for
循环,或 JDK 1.8 提供的 Stream 流,或 Google 的 Guava 集合库来实现。
FOR 循环
FOR 循环是在 JDK 1.8 之前最常用的方法,遍历每个元素,拿到单个元素的属值设置为 Map 的 key 和 value,或将 对象设置为 value。
FOR 循环对于 ArrayList 是非常高效的,是一种可靠优秀的选择。
Stream 流的方式
JDK 1.8 提供的 Stream 流的操作也是快捷高效的。
收集单个属性
Map<Long, String> maps = userList.stream().collect(Collectors.toMap(User::getId, User::geName));
Map<Long, String> maps = userList.stream().collect(Collectors.toMap(k -> k.getId, v -> v.getName));
收集对象
使用 Function 接口中的默认方式
Map<Long, User> maps = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
使用 Lambda 操作,返回对象本身
Map<Long, User> maps = userList.stream().collect(Collectors.toMap(User::getId, user -> user));
Key 为空处理
添加一个非空过滤
Map<String, String> userMap = userList.stream().filter(e -> StringUtils.isNotBlank(e.getName()) && StringUtils.isNotBlank(e.getCode())).collect(Collectors.toMap(User::getName, User::getCode));
Map<String, User> userMap = userList.stream().filter(e -> StringUtils.isNotBlank(e.getName())).collect(Collectors.toMap(User::getName, e -> e));
Key 重复处理
上面的方式是没有对重复的 key 进行处理的,重复 key 会报 (java.lang.IllegalStateException: Duplicate key)
的错误,toMap
有个重载方法,可以传入一个合并的函数为重复 Key 指定覆盖策略,如下方式:
// 对象,后则覆盖前者
Map<Long, User> maps = userList.stream().collect(Collectors.toMap(User::getId, Function.identity(), (key1, key2) -> key2));
// 属性
Map<Long, String> maps = userList.stream().collect(Collectors.toMap(User::getId, User::getAge, (key1, key2) -> key2));
指定 Map 的具体实现
toMap
还有一个重载方法,可以指定用何种类型的 Map 来收集数据。
public Map<String, Account> getNameAccountMap(List<Account> accounts) {
return accounts.stream().collect(Collectors.toMap(Account::getUsername, Function.identity(), (key1, key2) -> key2, LinkedHashMap::new));
}
Guava 方式
Map<Long, User> userMap = Maps.uniqueIndex(userList, new Function<User, Long>() {
@Override
public Long apply(User user) {
return user.getId();
}
});
更多内容请访问:IT源点
注意:本文归作者所有,未经作者允许,不得转载