Java 8 toMap IllegalStateException 重复键

Posted

技术标签:

【中文标题】Java 8 toMap IllegalStateException 重复键【英文标题】:Java 8 toMap IllegalStateException Duplicate Key 【发布时间】:2015-04-30 16:10:01 【问题描述】:

我有一个包含以下格式数据的文件

1
2
3

我想将其加载为(1->1), (2->1), (3->1)

这是 Java 8 代码,

Map<Integer, Integer> map1 = Files.lines(Paths.get(inputFile))
                .map(line -> line.trim())
                .map(Integer::valueOf)
                .collect(Collectors.toMap(x -> x, x -> 1));

我收到以下错误

Exception in thread "main" java.lang.IllegalStateException: Duplicate key 1

如何解决这个错误?

【问题讨论】:

当文件有两次相同的编号时,您希望发生什么? 如果有这样的情况,我想获取出现次数作为该键的值。因此,如果说密钥 2 在文件中出现 4 次,那么它将是 (2->4)。 那你就需要使用这个方法了:docs.oracle.com/javase/8/docs/api/java/util/stream/… 如果样本数据实际上包含重复项,我认为这个问题会更好 我遇到了同样的问题,错误信息不是误导吗?错误消息说重复键并打印出值 【参考方案1】:

如果您想将值映射到 1,pramodh 的回答很好。但如果您不想总是映射到常量,使用“合并函数”可能会有所帮助:

Map<Integer, Integer> map1 = Files.lines(Paths.get(inputFile))
                .map(line::trim())
                .map(Integer::valueOf)
                .collect(Collectors.toMap(x -> x, x -> 1, (x1, x2) -> x1));

上面的代码与问题中发布的几乎相同。但是如果它遇到duplicate key,它不会抛出异常,而是通过应用合并函数来解决它,取第一个值。

【讨论】:

这更有用。谢谢@KeyMaker00【参考方案2】:

如果文件中没有重复,代码将运行。

Map<Integer, Integer> map1 = Files.lines(Paths.get(inputFile))
            .map(String::trim)
            .map(Integer::valueOf)
            .collect(Collectors.toMap(x -> x, x -> 1));

如果有重复项,请使用以下代码获取文件中该键的出现总数。

Map<Integer, Long> map1 = Files.lines(Paths.get(inputFile))
            .map(String::trim)
            .map(Integer::valueOf)
            .collect(Collectors.groupingBy(x -> x, Collectors.counting());

【讨论】:

您可以使用collect(Collectors.groupingBy(x -&gt; x, Collectors.counting())),这可能比toMap() 的3-arg 形式更清晰。此外,您还可以使用String::trim 代替line -&gt; line.trim() @StuartMarks,我收到 Collectors.groupingsBy(x -> x, Collectors.counting() 的循环推理错误 啊,counting() 累积成一个Long,所以你必须将映射声明更改为Map&lt;Integer,Long&gt; 旁注:Files.lines 不会自动关闭文件 - 如果您经常这样做,您可能会遇到“打开的文件过多”错误。您可以使用 try-with-resources:try(Stream&lt;String&gt; lines = Files.lines(...)) lines.map(String::trim).... @assylias 对于未来的读者,他们在11 中修复了这个问题:通过关闭流来关闭文件。

以上是关于Java 8 toMap IllegalStateException 重复键的主要内容,如果未能解决你的问题,请参考以下文章

JDK1.8 Stream之toMap和groupingBy全参数的使用

JAVA集合05_Collection.toMap()应用三个重载方法解决重复key问题

Java stream操作toMap总结

java8的stream中Collectors.toMap空指针问题

Java8 stream操作toMap的key重复问题 原

Java中Collectors.toMap()的基本使用方法和使用场景