Java Streams抛出java.lang.IllegalStateException: Duplicate Key问题求助
解决Java Streams toMap重复键报错并保留多值的问题
嗨,我来帮你搞定这个问题~
首先,你遇到的IllegalStateException是因为默认的Collectors.toMap()方法在检测到重复键时,会直接抛出异常——它的默认合并策略就是冲突时报错,这就是你看到错误信息的根源。
你的需求是保留重复键的所有值,所以核心要改的是stream收集阶段的合并逻辑,而不是后面处理text的部分。你之前的尝试只处理了complex为空时的text存储,但问题出在complex.stream()的collect步骤:当多个子对象的toMap()返回相同键时,这里直接抛异常了,导致后续逻辑根本没机会执行。
修复方案:使用带合并函数的toMap重载方法
Collectors.toMap有一个重载版本,接受三个参数:键提取器、值提取器,以及合并函数——我们可以利用这个合并函数,把重复键的所有值收集到List里。
修改你的complexMap收集代码如下:
final Map<String, Object> complexMap = complex.stream() .flatMap(c -> c.toMap().entrySet().stream()) .collect(Collectors.toMap( Map.Entry::getKey, // 把每个单个值先包装成List entry -> { List<Object> valueList = new ArrayList<>(); valueList.add(entry.getValue()); return valueList; }, // 当键重复时,合并两个List (existingList, newValuesList) -> { existingList.addAll(newValuesList); return existingList; } ));
统一值类型(可选但推荐)
为了让整个Map的结构更统一,避免后续处理时的类型转换问题,建议把else分支的text也包装成List:
} else { List<Object> textList = new ArrayList<>(); textList.add(text); map.put(namespacePrefix.concat(":").concat(localName), textList); }
这样不管是单个值还是多个值,Map里的value都是List<Object>,后续读取和处理时会更顺畅。
为什么你之前的尝试没奏效?
你之前的代码是在尝试给单个key添加List,但问题出在前面的stream收集阶段——当多个子对象返回相同键时,Collectors.toMap()直接抛出了异常,根本没走到你处理text的逻辑。只有先解决stream阶段的重复键合并问题,整个方法才能正常执行。
内容的提问来源于stack exchange,提问作者BATMAN_2008
相关产品推荐
相关产品推荐

