Java 8 List 转 Map
这篇文章属于 Java 8 教程(LTS)系列教程,点击阅读更多相关文章。
本文介绍从 Java 8 开始,如何把一个 List 转换为 Map,以及如果出现了冲突的 key 该如何处理。
准备:Dog.java
package com.wdbyte.demo;
public class Dog {
private String name;
private Integer age;
public Dog() {
}
public Dog(String name, Integer age) {
this.name = name;
this.age = age;
}
// 省略 get set toString
}
1. Collectors.toMap
List
转 Map
可以使用 Java 8 中的 Collectors.toMap
进行转换。
示例1:把包含不同品种的狗类集合转换成 key
为狗的品种,value
为狗的年龄的 Map
。
package com.wdbyte.demo;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ListToMap {
public static void main(String[] args) {
List<Dog> list = new ArrayList<>();
list.add(new Dog("牧羊犬", 1));
list.add(new Dog("哈士奇", 2));
list.add(new Dog("田园犬", 3));
// to map,key dog name,value ,dog age
Map<String, Integer> dogMap = list.stream()
.collect(Collectors.toMap(Dog::getName, Dog::getAge));
System.out.println(dogMap);
}
}
输出结果:
{牧羊犬=1, 哈士奇=2, 田园犬=3}
示例2:把包含不同品种的狗类集合转换成 key
为狗的品种,value
为狗的信息对象的 Map
。
List<Dog> list = new ArrayList<>();
list.add(new Dog("牧羊犬", 1));
list.add(new Dog("哈士奇", 2));
list.add(new Dog("田园犬", 3));
// to map,key dog name,value ,dog age
Map<String, Dog> dogMap = list.stream()
.collect(Collectors.toMap(Dog::getName, dog -> dog));
System.out.println(dogMap);
输出结果:
{牧羊犬=Dog{, name='牧羊犬', age=1}, 哈士奇=Dog{, name='哈士奇', age=2}, 田园犬=Dog{, name='田园犬', age=3}}
2. List 转 Map,冲突 Key
还是上面的例子,如果有重复的 key 将会抛出异常。
示例1:List
转 Map
使用 Collectors.toMap
进行转换时,如果有 key 冲突。
package com.wdbyte.demo;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ListToMapDuplicateKey {
public static void main(String[] args) {
List<Dog> list = new ArrayList<>();
list.add(new Dog("牧羊犬", 1));
list.add(new Dog("牧羊犬", 2));
list.add(new Dog("哈士奇", 2));
list.add(new Dog("田园犬", 3));
// to map,key dog name,value ,dog age
Map<String, Integer> dogMap = list.stream()
.collect(Collectors.toMap(Dog::getName, Dog::getAge));
System.out.println(dogMap);
}
}
输出结果:在遇到重复 key 时,抛出了异常。
Exception in thread "main" java.lang.IllegalStateException: Duplicate key 牧羊犬 (attempted merging values 1 and 2)
at java.base/java.util.stream.Collectors.duplicateKeyException(Collectors.java:133)
at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Collectors.java:180)
at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
...
示例2:传入第三个参数,当Key 冲突时,选择使用新值。
List<Dog> list = new ArrayList<>();
list.add(new Dog("牧羊犬", 1));
list.add(new Dog("牧羊犬", 2));
list.add(new Dog("哈士奇", 2));
list.add(new Dog("田园犬", 3));
// to map,key dog name,value ,dog age
Map<String, Integer> dogMap = list.stream()
.collect(Collectors.toMap(Dog::getName, Dog::getAge, (oldData, newData) -> newData));
System.out.println(dogMap);
通过 (oldData, newData) -> newData)
来选择使用新值还是老值。
输出结果:
{牧羊犬=2, 田园犬=3, 哈士奇=2}
3. List 转 Map,指定 Map 类型
示例:传入第四个参数,指定 Map
类型。
public static void main(String[] args) {
List<Dog> list = new ArrayList<>();
list.add(new Dog("牧羊犬", 1));
list.add(new Dog("牧羊犬", 2));
list.add(new Dog("哈士奇", 2));
list.add(new Dog("田园犬", 3));
// to map,key dog name,value ,dog age
Map<String, Integer> dogMap = list.stream()
.collect(Collectors.toMap(Dog::getName, Dog::getAge,
(oldData, newData) -> newData,
ConcurrentHashMap::new));
System.out.println(dogMap.getClass());
}
输出结果:
class java.util.concurrent.ConcurrentHashMap