Java Set of Maps hashCode 不正确?

标签 java hashmap hashcode

我从一组 map ( Set<Map<String,String>> ) 中得到了意想不到的结果,其中 s.contains(s.iterator().next())false .

有问题的集合只包含一张 map ,即 [{=262.666666666666667}] (映射到字符串 262.666666666666667 的空字符串)。

我一直无法组合一个最小的工作示例来复制问题,因为以下输出为真:

Set s = new HashSet<Map<String,String>>();
Map<String,String> m = new HashMap<>();
m.put("", "262.666666666666667");
s.add(m);
System.out.println(s.contains(s.iterator().next()));

HashMap 不会覆盖 hashCode 但 Abstract map 会覆盖(见下文)所以我没有看到将 HashMap 放入 HashSet 中的问题。

public int hashCode()
{
     int h = 0;
     Iterator<Entry<K,V>> i = entrySet().iterator();
     while (i.hasNext())
         h += i.next().hashCode();
     return h;
}

此行为的原因是什么,我该如何解决?

编辑:感谢 doublep 和 morgano,我确实在添加后修改了 map ,并通过在修改后而不是之前添加来解决了问题。

最佳答案

如果您想重现错误,请按以下方式修改您的代码:

    Set s = new HashSet<Map<String,String>>();
    Map<String,String> m = new HashMap<>();
    s.add(m);
    m.put("", "262.666666666666667");
    System.out.println(s.contains(s.iterator().next()));

也就是将map添加到set中,然后在map中放入一个新的key/value。

问题是,正如您所说,抽象映射重写 equals() 以依赖于映射当时持有的键/值。 Set 在内部使用一个 Map,在您的 Map 被添加到集合中时,它是 equals() 的值的键。当您向 Map 添加新的键/值时,equals() 返回的值也会发生变化并且与原始值不对应,这样您对于 System.out 会得到 false .println(s.contains(s.iterator().next()));

关于Java Set of Maps hashCode 不正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29276397/

相关文章:

java - 修改应用程序 web.xml 中的 JspServlet 配置?

java - 为什么这种并行矩阵加法效率如此低下?

java - 如何使用 Jackson 从 JSON 文件加载多个 HashMap

android - 在应用程序中存储 hashmap 数据

java - hashcode 和 equals 方法未被覆盖 - put 和 get 将如何工作?

Hadoop 的默认分区器 : HashPartitioner - How it calculates hash-code of a key?

Java Map 哈希码

java - 响应 409,共享首选项管理器

java - JUnit Spring 4 MVC 集成测试失败并出现 BeanCreationException : Error creating bean

java - 比较 Java 中的 2 个 HashMap