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.

3
  • 1
    Wrap the keys with an object that overrides the equals/hashCode properly. Commented Mar 2, 2014 at 11:10
  • ... or use TIntArrayList, which wraps an int[] Commented Mar 2, 2014 at 11:15
  • possible duplicate of Can a java array be used as a HashMap key Commented Feb 26, 2015 at 13:10

5 Answers 5

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Or pass a custom Comparator to the Map's constructor.
@kocko You can do that for TreeMap, but not HashMap.
@kocko Is treemap very different from hashmap, if not, i would rather use a map that just need to pass a comparator
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.

Comments

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

Comments

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

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.