鉴于以下代码,我得到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
)等的地图开放,条件是如果不妨碍地图访问时间的有效性
答案 0 :(得分:7)
无法使用数组,因为它们不会覆盖equals()和hashCode()。您应该定义自己的包装数组的类,它将覆盖equals()
和hashCode()
或使用List<Integer>
代替。
答案 1 :(得分:3)
将它们包装在自定义对象中,并使用Arrays.equals(array1, array2)
进行相等操作。来自api:
如果两个指定的int数组等于1,则返回true 另一个。如果两个数组都包含,则认为两个数组相等 相同数量的元素,以及所有相应的元素对 这两个数组相等。换句话说,两个数组是相等的 包含相同顺序的相同元素。另外,两个阵列 如果两者都为空,则认为引用是相等的。
答案 2 :(得分:2)
问题是int[]
使用equals()
和hashCode()
的对象标识,因此它不适用于java中的Map。您可以改为使用List<Integer>
。
列表的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()); }
答案 3 :(得分:1)
Arrays类使用Object类的默认equels和hashcode,但是它提供了另一个名为deepHashCode和deepEquls的方法,它们实际上在数组中包含。您可以创建一个类似下面的类来保存您的数组,并使用deepHashCode和deepEquals实现hashcode和equals。而不是直接数组使用此类。
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