具有哈希码功能的类

时间:2012-01-09 22:01:22

标签: java hashcode

我想检查上面代码中是否以正确的方式使用hashcode函数。我注意到map有一些奇怪的空值和0值而不是{1,2,3}。

public class Test {

public static void main(String[] args) {
    int[] array = {1,2,3}; 
    Map<Row, Integer> map = map(array);
}

static class Row extends Object {
        private int value;
        private volatile int hashCode = 0;

        public Row(int val) {
            this.value = val;
        }

        @Override
        public boolean equals(Object obj) {
            if(this == obj)
                return true;
            if((obj == null) || (obj.getClass() != this.getClass()))
                return false;
            // object must be Row at this point
            Row row = (Row)obj;
                return (value == row.value);
        }

        @Override
        public int hashCode () {
            final int multiplier = 7;
            if (hashCode == 0) {
                int code = 31;
                code = multiplier * code + value;
                hashCode = code;
            }
            return hashCode;
        }
    }

    private static Map<Row, Integer> map(int[] array) {
          Map<Row, Integer> arrayMap = new HashMap<Row, Integer>();
          for (int i=0; i<array.length; i++)
                arrayMap.put(new Row(array[i]), i);
          return arrayMap;
    }
}

2 个答案:

答案 0 :(得分:4)

你到底遇到了什么问题?如果我向toString类添加Row方法:

@Override
public String toString() {
    return Integer.toString(value);
}

然后打印地图:

public static void main(String[] args) {
    int[] array = { 1, 2, 3 };
    Map<Row, Integer> map = map(array);
    System.out.println(map);
}

打印:{3=2, 1=0, 2=1}。这似乎是正确的。

答案 1 :(得分:1)

你的hashCode看起来对我来说是正确的,除了value字段应该是final以使类不可变并因此是线程安全的,但它太复杂了。 Row只是int值的包装器。 hashCode可以缩减为:

return this.value;

或者你可以完全避免使用Row类,并使用Integer来包装你的int值。