Java中将List转为Map
1. 建立对象类
1 |
|
2. 建立Main函数
1 | public class Main |
3. 当key有可能重复时,给出合并策略
当key有重复时,Collectors.toMap()方法将抛出java.lang.IllegalStateException: Duplicate key异常,因此需要给出合并策略:1
2
3
4
5
6
7
8
9
10
11
12
13
14public static void main(String[] args)
{
List<User> userList = Lists.newArrayList();
userList.add(new User("1", "张三", "男", "北京"));
userList.add(new User("2", "李四", "女", "上海"));
userList.add(new User("3", "王五", "男", "南京"));
userList.add(new User("4", "张三", "男", "广州"));
// 当key重复时,用新值覆盖旧值 (oldValue, newValue) -> newValue,若改为oldValue,则忽略新值保留旧值
Map<String, String> nameToCityMap =
userList.stream().collect(Collectors.toMap(User::getName, User::getCity, (oldValue, newValue) -> newValue));
printMap(nameToCityMap);
}
4. 当stream中可能存在null元素时,先filter过滤
当stream中存在null元素时,Collectors.toMap()方法将抛出NPE异常,因此需要先filter过滤出不为空的元素,再进行转换。1
2
3
4
5
6
7
8
9
10
11
12
13
14public static void main(String[] args)
{
List<User> userList = Lists.newArrayList();
userList.add(new User("1", "张三", "男", "北京"));
userList.add(new User("2", "李四", "女", "上海"));
userList.add(new User("3", "王五", "男", "南京"));
userList.add(null);
Map<String, String> nameToCityMap = userList.stream()
.filter(Objects::nonNull)
.collect(Collectors.toMap(User::getName, User::getCity, (oldValue, newValue) -> newValue));
printMap(nameToCityMap);
}
5. 当Map的value值有可能为null时,先filter过滤
当map的value为null时,Collectors.toMap()方法将抛出NPE异常,因此需要先filter过滤,再进行转换。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public static void main(String[] args)
{
List<User> userList = Lists.newArrayList();
userList.add(new User("1", "张三", "男", "北京"));
userList.add(new User("2", "李四", "女", "上海"));
userList.add(new User("3", "王五", "男", "南京"));
userList.add(new User("4", "小明", "男", null));
Map<String, String> nameToCityMap = userList.stream()
.filter(Objects::nonNull)
.filter(user -> StringUtils.isNotEmpty(user.getCity()))
.collect(Collectors.toMap(User::getName, User::getCity, (oldValue, newValue) -> newValue));
printMap(nameToCityMap);
}
Tips:
集合类 | key | value | 父类 | 说明 |
---|---|---|---|---|
HashMap | 可以为null | 可以为null | AbstractMap | 底层数组+链表实现,线程不安全 |
ConcurrentHashMap | 不能为null | 不能为null | AbstractMap | 线程局部安全 |
HashTable | 不能为null | 不能为null | Dictionary | 底层数组+链表实现,线程安全 |
TreeMap | 不能为null | 可以为null | AbstractMap | 线程不安全 |
6. 加上排序
将list转化为map时,如果需要排序,只需加上sorted()方法并转换为LinkedHashMap即可。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public static void main(String[] args)
{
List<User> userList = Lists.newArrayList();
userList.add(new User("2", "李四", "女", "上海"));
userList.add(new User("1", "张三", "男", "北京"));
userList.add(new User("4", "小明", "男", "广州"));
userList.add(new User("3", "王五", "男", "南京"));
Map<String, String> nameToCityMap = userList.stream()
.sorted(Comparator.comparing(User::getId))
.collect(Collectors.toMap(User::getName,
User::getCity, // key为name,value为city
(oldValue, newValue) -> newValue, // key重复时保留新值
LinkedHashMap::new)); // 保留顺序
printMap(nameToCityMap);
}
7. 转换为分组Map
7.1 Collectors.groupingBy
和SQL中的group by语句类似,这里的groupingBy()也是按照某个属性对数据进行分组,属性相同的元素会被对应到Map的同一个key上。1
2
3
4
5
6
7
8
9
10
11
12
13public static void main(String[] args)
{
List<User> userList = Lists.newArrayList();
userList.add(new User("1", "张三", "男", "北京"));
userList.add(new User("2", "李四", "女", "上海"));
userList.add(new User("3", "王五", "男", "南京"));
userList.add(new User("4", "小明", "男", "北京"));
// 按照城市分组,value是个list
Map<String, List<User>> cityToUserMap = userList.stream().collect(Collectors.groupingBy(User::getCity));
printMap(cityToUserMap);
}
7.2 Collectors.partitioningBy
这种情况适用于将Stream中的元素依据某个二值逻辑(满足条件,或不满足)分成互补相交的两部分,比如男女性别、年龄是否达到18岁等。
partitioningBy是一种特殊的groupingBy。1
2
3
4
5
6
7
8
9
10
11
12
13
14public static void main(String[] args)
{
List<User> userList = Lists.newArrayList();
userList.add(new User("1", "张三", "男", "北京"));
userList.add(new User("2", "李四", "女", "上海"));
userList.add(new User("3", "王五", "男", "南京"));
userList.add(new User("4", "小明", "男", "北京"));
// key是Boolean,value是个list
Map<Boolean, List<User>> femaleMap =
userList.stream().collect(Collectors.partitioningBy(user -> StringUtils.equals(user.getSex(), "女")));
printMap(femaleMap);
}
Read More
[1]Java Stream API进阶篇
[2]Java 8 – Convert List to Map
[3]How to Convert List to Map in Java
[4]Java 8 – Convert stream to Map
[5]Java 8 Stream - From List to Map