【问题标题】:HashMap<int[],string> mapping integer array by considering their valuesHashMap<int[],string> 通过考虑它们的值来映射整数数组
【发布时间】:2014-03-02 11:08:29
【问题描述】:

给定以下代码,我得到一个null(我想要的是“1234”)。但是我希望有一个可以将键视为相等的映射,如果int[]的内容相等(而不是考虑int[]的引用),我该怎么做?

HashMap<int[], String> maps=new HashMap<int[], String>();
int[] i=new int[]{1,2,3};
int[] j=new int[]{1,2,3};
maps.put(i,"1234");
System.out.print(maps.get(j));

我对任何允许将 int[] 保留为键(包括 TreeMap)等的地图持开放态度,附带条件是,如果这不会影响地图访问时间的有效性。

【问题讨论】:

标签: java map hashmap


【解决方案1】:

数组无法做到这一点,因为它们不会覆盖 equals() 和 hashCode()。您应该定义自己的类来包装数组,这将覆盖 equals()hashCode() 或使用 List&lt;Integer&gt; 作为键。

【讨论】:

  • 或者将自定义的Comparator 传递给地图的构造函数。
  • @kocko 你可以对 TreeMap 这样做,但不能对 HashMap 这样做。
  • @kocko treemap和hashmap有很大不同吗,如果没有,我宁愿用一个只需要通过比较器的map
【解决方案2】:

将它们包装在自定义对象中,并使用Arrays.equals(array1, array2) 表示相等。来自api:

如果两个指定的 int 数组等于 1,则返回 true 其他。如果两个数组都包含 相同数量的元素,以及所有对应的元素对 两个数组相等。换句话说,两个数组相等,如果它们 以相同的顺序包含相同的元素。另外,两个数组 如果两者都为空,则认为引用相等。

【讨论】:

    【解决方案3】:

    问题在于int[] 使用equals()hashCode() 的对象标识,因此它不适用于Java 中的Map。你可以改用List&lt;Integer&gt;

    列表的hashCode() API 说

    返回此列表的哈希码值。列表的哈希码是 定义为以下计算的结果:

    int hashCode = 1;
      Iterator<E> i = list.iterator();
      while (i.hasNext()) {
          E obj = i.next();
          hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
      }
    

    【讨论】:

      【解决方案4】:

      Arrays 类使用 Object 类的默认 equels 和 hashcode,但它提供了另一种称为 deepHashCode 和 deepEquls 的方法,它们实际上对包含的数组起作用。您可以创建一个如下所示的类来保存您的数组,哈希码和等号将使用 deepHashCode 和 deepEquals 实现。而不是直接数组使用这个类。

      class MyArray {        
          private Integer[] arrayInstance;
      
          public void setArray(Integer[] a) {
                  this.arrayInstance = a;
          }
      
          @Override
          public int hashCode() {
                  final int prime = 31;
                  int result = 1;
                  result = prime * result + Arrays.deepHashCode(arrayInstance);
                  return result;
          }
      
          @Override
          public boolean equals(Object obj) {
                  if (this == obj)
                          return true;
                  if (obj == null)
                          return false;
                  if (getClass() != obj.getClass())
                          return false;
                  MyArray other = (MyArray) obj;
                  if (!Arrays.deepEquals(arrayInstance, other.arrayInstance))
                          return false;
                  return true;
          }
      }
      

      这就是你如何使用这个类

          Integer[] a = {1,2,3,4};
          Integer[] b = {1,2,3,4};
      
          MyArray m1 = new MyArray();
          m1.setArray(a);
      
          MyArray m2 = new MyArray();
          m2.setArray(b);
      
          Map<MyArray, String> m = new HashMap<MyArray, String>();
          m.put(m1, "M1");
          m.put(m2, "M2");
      
          System.out.println(m.size()); // It would be one
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-24
        • 2010-10-29
        • 1970-01-01
        • 1970-01-01
        • 2020-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多