简体   繁体   中英

Implementation of hashCode and equals in int[] Java

It looks like the hashCode() and equals() for int[] are poorly implemented, or not implemented at all! (Tested with Android, but I expect it to be true for any Java environment).

In order to get HashSet.contains() working properly, I had to create a wrapper for int[] (plse, don't criticize my coding style, look at the essence):

public class IntArray {
    private int[] value;

    public IntArray(int[] value) {
        this.value = value;
    }

    @Override
    public int hashCode() {
        int sum = 0;
        // Integer overflows are cheerfully welcome.
        for (int elem: value) sum += elem;
        return sum;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null) return (value==null);

        if (value != null) {
            if (o instanceof int[]) 
                return compare((int[])o);

            if (o instanceof IntArray)
                return compare(((IntArray)o).value);
        }

        return false;
    }

    protected boolean compare(int[] other) {
        int len = value.length;
        if (other.length != len) return false;
        for (int i=0; i<len ; i++)
            if (value[i] != other[i]) return false;
        return true;
    }
}

Works OK, but I prefer to avoid a custom wrapper or a third-party library. Is there an option?

Since the standard Java Hashtable does not allow an override of the hash code used for keys, you are out of luck and will need to use a wrapper like you did.

keep in mind that your hashCode implementation is very bad, you can use this (Taken from java.util.Arrays in the standard JDK) to get a better hash distrubtion:

public static int hashCode(int a[]) {
  if (a == null)
    return 0;

  int result = 1;
  for (int element : a)
    result = 31 * result + element;
  return result;
}

An alternative is to use a different Hashtable, which can deal with primitives. one such option is Banana , which is a primitive collections library I created.

After Omry Yadan's message the hashCode function becomes as simple as that!

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

For a RISC CPU, like ARM, It may be more efficient:

    @Override
    public int hashCode() {
        int code = 0;
        if (value != null) {
            code++;
            for (int elem: value)
                code = (code<<5) - code + elem;
        }
        return code;
    }

May be there is also a standard function for comparing arrays, in which case equals() can be simplified too?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM