【问题标题】:HashMap is returning wrong value for Integer keyHashMap 为 Integer 键返回错误值
【发布时间】:2016-05-13 15:22:21
【问题描述】:

我有一个HashMap下面的HashMap

private Map<Integer, List<CustomClass>> map = new HashMap<>();

我正在尝试在 HashMap 中针对 Integer 键添加一个新条目,如果该键存在,那么我想获取相应的列表并在其中添加新项目。代码如下。

        if (this.map.containsKey(//Integer Key)) {
            this.map.get(//Integer Key).add(//New List Item);
        } else {
            List<CustomClass> customClass = new ArrayList<>();
            customClass.add(new CustomClass());
            this.map.put(//Integer Key, customClass);
        }

真正的问题在于密钥已经存在的部分,我尝试使用 HashMap 获取函数

this.map.get(//Integer Key).add(//New List Item);

如果找不到 Integer 键的值,则不给出 null,但它经常给出错误的 ArrayList。现在我知道 HashMap 可以与 equals 和 hashCode 一起使用,所以我尝试覆盖这些函数并使用它们而不是整数键。

public class CustomHashMapIntegerKey {

    private Integer key = 0;

    public void setKey(Integer key) {
        this.key = key;
    }

    public Integer getKey() {
        return this.key;
    }

    @Override
    public int hashCode() {
        return this.key.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (null == obj) return false;
        if (this.getClass() != obj.getClass()) return false;
        final CustomHashMapIntegerKey customHashMapIntegerKey = (CustomHashMapIntegerKey) obj;
        if (null == this.key && null != customHashMapIntegerKey.getKey()) return false;
        if (null != this.key) {
            if (!this.key.equals(customHashMapIntegerKey.getKey())) return false;
        }
        return true;
    }
}

并更改了我的地图以使用这个新类作为键而不是整数,但我仍然遇到 HashMap 给出错误值的相同问题。此链接https://gist.github.com/MAnfal/dc581234ce597a8ff062

提供了一些详细的片段

【问题讨论】:

  • 如果 HashMap 中存在错误,您可以在 Google 搜索中找到相关信息(并且已经修复)。 java.lang.Integer 也是极不可能有错误的东西。问题的最可能原因是您向 Map.get() 方法提供了错误的整数。
  • 我使用调试器进行了双重检查,包括我的键的 instanceof、value、布尔值与从 hashmap 获得的值。我并不是说它的 java 的错,但不知何故,我尝试的一切都没有给我适当的结果。
  • 哈希取决于键,如果它是一个整数,那么“给[你]一个错误的 ArrayList”的可能性很小。重新检查您的代码。
  • 如果可能的话,分享你的整个代码
  • Integer 类已经实现了equalshashcode 方法,所以不需要CustomHashMapIntegerKey。除非应用程序逻辑做错了什么,否则它应该可以工作。可能是多线程问题。是否有多个线程试图读取和写入 HashMap。如果是这样,请考虑使用synchronized Map 或更好的ConcurrentHashMap

标签: java hashmap


【解决方案1】:

HashMap 部分依赖equalshashCode 来完成它的工作,但它有点复杂。请查看this article 以获得深入的解释。

为了您的目的(以列表为值的地图),我建议使用来自 Google 的 Guava 库的Multimap

ListMultimap<Integer, String> multimap = ArrayListMultimap.create();
multimap.put(4, "Is the first digit of '4'");
multimap.put(4, "Is the first digit of '42'");
multimap.put(4, "Is the first digit of '4711'");
multimap.put(1, "Is the first digit of '13'");

Collection<String> values = multimap.get(4);

Collectionvalues 将包含您在 4 键下添加的三个元素。

【讨论】:

  • 我知道 HashMap 使用 hashCode 和 equals,感谢您的建议,但我现在会坚持使用 Guava,我不想将整个库用于可以通过核心 java 实现的单个功能。
【解决方案2】:

我怀疑存储在您的地图中的值。根据您提供的详细信息,您的问题可能只发生在一种情况下,您必须在不同的列表中添加相同的对象并在 HashMap 中使用不同的键存储。记录您的地图内容,并打印对象哈希码,这可能会对您有所帮助

【讨论】:

  • 我检查了日志,我在同一个列表中添加了不同的对象,这些对象与地图的唯一共同点是项目 ID(作为地图的键传递)。为了在数组列表中组合具有相同 id 的项目,我使用了这种数据结构。
  • 能分享一下调用这个方法的代码吗?
  • 说如果项目的 id 为 3 并将其存储在列表中并使用键 3 放入 Map 中,下次您获得 id 为 3 的项目时,它应该获得所有列表项目具有相同的 ID。但是您看到的是一个列表,其中包含项目 ID 为其他内容的项目。我的理解正确吗?
  • 不,我的意思是调用 addToDepartmentItemMap 方法的代码,如果可能的话,也传递 departmentItemHolder 和 departmentItemHolder 类
  • 我也遇到了同样的问题。
猜你喜欢
  • 1970-01-01
  • 2013-10-24
  • 2019-08-12
  • 1970-01-01
  • 1970-01-01
  • 2019-08-11
  • 2016-03-16
  • 2011-11-23
相关资源
最近更新 更多