【问题标题】:HashMap with ArrayList key can not find it when Arraylist grows当 Arraylist 增长时,带有 ArrayList 键的 HashMap 无法找到它
【发布时间】:2012-02-04 14:22:32
【问题描述】:

我的问题是,例如,在我的代码的某些部分中,我使用数组列表作为哈希图中的键

ArrayList<Integer> array = new ArrayList<Integer>();

然后我把我的数组像一个键一样放在哈希映射中(我确信我需要它)

HashMap<ArrayList<Integer>, String> map = new HashMap<ArrayList<Integer>, String>();
map.put(array, "value1");

问题来了:当我向我的数组添加一些值,然后我尝试使用相同的数组恢复数据时,哈希映射无法找到它。

array.add(23);
String value = map.get(array);

此时value为null而不是字符串“value1” 我正在测试,我发现当数组列表增长时 hashCode 会发生变化,这是我问题的中心点,但我想知道如何解决这个问题。

【问题讨论】:

  • 我几乎可以肯定您不会想要这样做。您更有可能想要Map&lt;String, List&lt;Integer&gt;&gt;
  • 非常感谢您的回答,但我很确定我需要这种方式...

标签: java arraylist hashmap hashcode


【解决方案1】:

您不能使用可变对象(即hashCode 更改的对象)作为HashMap 的键。看看你是否能找到其他东西来代替钥匙。将集合映射到字符串有点不寻常。反过来更常见。

【讨论】:

    【解决方案2】:

    这是一个奇怪的用例,但如果你必须这样做,那么你可以对数组进行子类化并覆盖 hashCode 方法。

    【讨论】:

      【解决方案3】:

      使用IdentityHashMap。然后,相同的数组实例将始终映射到相同的值,无论其内容(以及因此哈希码)如何更改。

      【讨论】:

        【解决方案4】:

        我几乎可以肯定你不想这样做。您更有可能想要Map&lt;String, List&lt;Integer&gt;&gt;。但是,如果您绝对必须这样做,请使用持有者类:

        public class ListHolder {
            private List<Integer> list = new ArrayList<Integer>();
            public List<Integer> getList() {return list;}
        }
        
        Map<ListHolder, String> map = new HashMap<ListHolder, String>;
        

        【讨论】:

        • 这实际上不起作用 - 您不能创建通用对象数组。持有者类会更合适。
        【解决方案5】:

        在我看来,这是一件可以尝试和做的事情。

        我假设您要建模的是由 n 个整数组成的可变长度键,并假设 ArrayList 的哈希值将是一致的,但我不确定是这样的。

        我建议您将ArrayList 子类化并覆盖hash()equals() 方法,或者将HashMap 包装在一个密钥类中。

        【讨论】:

          【解决方案6】:

          基本原因:当我们使用 HashMap.put(k, v) 时,它会对 k.hashCode() 进行数字化,以便它知道放在哪里。

          它还通过这个数字找到值(k.hashCode());

          你可以看到 ArrayList.hashCode() 函数,它在 AbstractList 的抽象类中。显然,在我们添加一些对象之后,它会改变 haseCode 的值。所以我们找不到使用HashMap.get(K)的值,也没有hashCode为K的元素。

          public int hashCode() {
              int hashCode = 1;
              for (E e : this)
                  hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
              return hashCode;
          }
          

          【讨论】:

            猜你喜欢
            • 2014-08-04
            • 2016-07-21
            • 1970-01-01
            • 2014-09-21
            • 2016-08-28
            • 1970-01-01
            • 1970-01-01
            • 2018-02-06
            • 2012-04-15
            相关资源
            最近更新 更多