1. 场景还原
1. 伪代码
public static void main(String[] args) {
ArrayList<User2> list = new ArrayList<>();
list.add(new User2(1, "2"));
list.add(new User2(1, "3"));
list.add(new User2(1, "4"));
Map<Integer, User2> collect = list.stream()
.collect(Collectors.toMap(e -> e.getId(), e -> e));
}
@Data
public class User2 {
private int id;
private String name;
public User2() {
}
public User2(int id, String name) {
this.id = id;
this.name = name;
}
}
2. 控制台现象
Connected to the target VM, address: '127.0.0.1:59601', transport: 'socket'
Exception in thread "main" java.lang.IllegalStateException: Duplicate key User2(id=1, name=2)
at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
at java.util.HashMap.merge(HashMap.java:1254)
at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
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 model.ProducerConsumerTest.main(ProducerConsumerTest.java:20)
Disconnected from the target VM, address: '127.0.0.1:59601', transport: 'socket'
糟糕报错了。。。Duplicate key表示的是重复Key,无法区分。。
2. 错误做法
Map<Integer, User2> collect = list.stream()
.collect(Collectors.toMap(e -> e.getId(), e -> e));
本方法是采用Collectors中的toMap方法,只有两个入参
- key是什么?
- value是什么?
3. 正确做法
Map<Integer, User2> collect = list.stream()
// 当出现重复key时,默认取老的
.collect(Collectors.toMap(e -> e.getId(), e -> e, (k1, k2) -> k1));
本方法在上面那个方法的基础上,多了一个mergeFunction入参,就是代表如果key对应的字段发送重复的时候的选取规则(选老的还是选新的)
问题解决,完结撒花~