简体   繁体   English

hashCode和equals在int [] Java中的实现

[英]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! 看来int []的hashCode()和equals()实现不佳,或者根本没有实现! (Tested with Android, but I expect it to be true for any Java environment). (已经在Android上进行了测试,但是我希望它在任何Java环境中都是正确的)。

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): 为了使HashSet.contains()正常工作,我必须为int []创建包装器(请注意,不要批评我的编码风格,请看本质):

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. 由于标准Java Hashtable不允许覆盖用于键的哈希码,因此您很不走运,因此需要像以前一样使用包装器。

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: 请记住,您的hashCode实现非常糟糕,您可以使用此代码(从标准JDK中的java.util.Arrays中获取)来获得更好的哈希分配:

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. 一个这样的选项是Banana ,这是我创建的原始集合库。

After Omry Yadan's message the hashCode function becomes as simple as that! 在Omry Yadan发出消息之后,hashCode函数就变得如此简单!

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

For a RISC CPU, like ARM, It may be more efficient: 对于像ARM这样的RISC CPU,效率可能更高:

    @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? 也许还有一个比较数组的标准函数,在这种情况下equals()也可以简化?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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