4

Given the following code, I get a null (what I want is "1234"). But I wish to have a map that could consider the key as equals, if the contents of int[] are equals (rather than consider that the references of int[]), how should I do it?

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));

I am opened to any map that allows keeping int[] as the key (including TreeMap) and so on, with the side condition that if that does not hamper on the effectiveness of the map accessing time.

Trein
  • 3,658
  • 27
  • 36
william007
  • 17,375
  • 25
  • 118
  • 194

5 Answers5

8

No way to do that with arrays, because they don't override equals() and hashCode(). You should define your own class wrapping the array, which would override equals() and hashCode() or use a List<Integer> as key instead.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
3

Wrap them in a custom object, and use Arrays.equals(array1, array2) for equality. From the api:

Returns true if the two specified arrays of ints are equal to one another. Two arrays are considered equal if both arrays contain the same number of elements, and all corresponding pairs of elements in the two arrays are equal. In other words, two arrays are equal if they contain the same elements in the same order. Also, two array references are considered equal if both are null.

Zavior
  • 6,412
  • 2
  • 29
  • 38
2

The problem is that int[] uses object identity for equals() and hashCode(), so it won't work with Map in java. You can use List<Integer> instead.

List's hashCode() API says

Returns the hash code value for this list. The hash code of a list is defined to be the result of the following calculation:

int hashCode = 1;
  Iterator<E> i = list.iterator();
  while (i.hasNext()) {
      E obj = i.next();
      hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
  }
Abimaran Kugathasan
  • 31,165
  • 11
  • 75
  • 105
1

Arrays class use the default equels and hashcode of Object class but it provide another methods called deepHashCode and deepEquls that actually work on the array contains. You can create a class like below that hold your array and the hashcode and equals will be implemented using deepHashCode and deepEquals. Instead of direct array use this class.

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;
    }
}

This is how you can use this class

    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
Naveen Ramawat
  • 1,425
  • 1
  • 15
  • 27
0

One approach is to define your own class wrapping the array, which would override equals() and hashCode() as shown below:

class CustomArrayClass {
    int[] array;
    CustomArrayClass(int n){
        array = new int[n];
    }

    @Override
    public boolean equals(Object obj){
        if(obj==null || !(obj instanceof CustomArrayClass)){
            return false;
        }
        if(this == obj){
            return true;
        }
        CustomArrayClass sec = (CustomArrayClass) obj;
        return Arrays.equals(this.array, sec.array);
    }

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

    @Override
    public String toString(){
        return Arrays.toString(this.array);
    }
}
pankaj
  • 41
  • 4