Java 流抛出 java.lang.IllegalStateException:重复键

BAT*_*008 0 java collections dictionary java-stream collectors

我对 Java 流有点陌生,并遇到了以下问题。我尝试了该网站和各种文章中提到的许多内容,但无法修复它们,因此将问题发布在这里。

我正在我的应用程序中创建一个Map<String, Object>using JavaStreams,然后将值传递给Map带有重复项的keys,然后它会抛出以下错误:

java.lang.IllegalStateException: Duplicate key namespace:localName (attempted merging values [ONE] and [TWO])

    at java.base/java.util.stream.Collectors.duplicateKeyException(Collectors.java:133)
Run Code Online (Sandbox Code Playgroud)

以下是引发此错误的方法:

public Map<String, Object> toMap() {
    final Map<String, Object> map = new HashMap<>();
    if (complex != null && complex.size() > 0) {
        final Map<String, Object> complexMap = complex.stream()
                .flatMap(c -> c.toMap().entrySet().stream())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        map.put(namespacePrefix.concat(":").concat(localName), complexMap);
    } else {
        map.put(namespacePrefix.concat(":").concat(localName), text);
    }
    return map;
}
Run Code Online (Sandbox Code Playgroud)

我尝试制作Objectas ,List以便如果发现重复值,则将其添加到List如下所示的内容中:

List<Object> values = (List<Object>) map.get(namespacePrefix.concat(":").concat(localName));
if (values == null) {
    values = new ArrayList<Object>();
}
values.add(text);
map.put(namespacePrefix.concat(":").concat(localName), values);
Run Code Online (Sandbox Code Playgroud)

但这似乎对我也不起作用。如果键重复,我想保留这两个值,因为我需要应用程序中的所有值。有人可以向我解释一下我在这里做错了什么以及如何解决它的一些想法吗?

Nik*_*las 6

使用方法不允许重复Collectors.toMap(Function, Function)

如果映射的键包含重复项(根据Object.equals(Object)),则会抛出 IllegalStateException。

现在这取决于您喜欢什么输出:

  • Map<String, Object>

    您需要使用Collectors.toMap(Function, Function, BinaryOperator)合并函数来决定出现相同键时应使用哪个值。

    如果映射的键包含重复项(根据 Object.equals(Object)),则将值映射函数应用于每个相等的元素,并使用提供的合并函数合并结果。

    此解决方案需要知道如何处理两个或多个重复的键。

  • Map<String, List<Object>>

    您需要使用分组收集器Collectors.groupingBy(Function),通过键对所有值进行分组,即以前的值出现在Listas 值中。如果前一个键重复,则新键Map将出现一次,并且List作为值将具有多个元素。

    返回一个 Collector,对类型 T 的输入元素实现“group by”操作,根据分类函数对元素进行分组,并在 Map 中返回结果。

    该解决方案为您添加了一个选项来识别重复字段并稍后决定如何处理这些值。