背景:生产环境有一个批量创建问文件夹的接口,接口逻辑一次传入多个文件夹名称,去发号器批量申请文件夹id
某个场景下前端入参的文件夹名称重复,导致服务端报错如下
代码:
public class MyTest {
public static void main(String[] args) {
List mydtoList= new ArrayList<>(2);
mydto a = new mydto();
a.setId(100L);
a.setName("a");
mydto b = new mydto();
b.setId(101L);
b.setName("a");
mydtoList.add(a);
mydtoList.add(b);
Map d =mydtoList.stream().collect(Collectors.toMap(mydto::getName,mydto::getId));
}
}
class mydto {
private String name;
private Long id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
Exception in thread "main" java.lang.IllegalStateException: Duplicate key 100 at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133) at java.util.HashMap.merge(HashMap.java:1256) 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:1384) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) 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 com.fancv.MyTest.main(MyTest.java:21)神奇的报错信息
jdk 1.8 的报错信息有误导性性, Duplicate key 100,让人容易理解 id重复了,事实上市 name 重复了,可能是幸运女神眷顾,在整个业务场景下爆出这错,团队成员都误认为是id重复了,耽误了半天时间,后边证实是 name重复了
相比之下 jdk 11 的提示信息友好很多
Exception in thread "main" java.lang.IllegalStateException: Duplicate key a (attempted merging values 102 and 101) 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) at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) at com.fancv.MyTest.main(MyTest.java:21)排查问题的思考
jdk1.8 的报错信息已经定位到具体行数,根据上下文可以推理出不可能id重复,如果是其他业务场景和id没关系,追到这也就可以了
排查问题尽可能的还原现场,排除干扰, 有自己的判断,当然基础是自己技术扎实。



