[Effective Java] The hashCode method must be rewritten when the equals method is rewritten

It must be remembered: for every class, equalswhen you override a method, you must override the hashCodemethod. Failure to do so will cause problems in all hashcomputation-based classes such as HashMap, HashSetand HashTable.

hashCodeconvention

ObjectThere is such a convention in the specification:

  • If the same object is called multiple times during the same execution of the program, the hash value must return the same. But not the same calling process does not have to be the same;
  • If two objects call the equals() method the same, the return value of the hashCode() method must be the same;
  • If the equals() method is called on two objects that are not the same, it is not necessary that the hash values ​​of the two objects are not the same. But developers must be aware that different hash values ​​for different objects can improve the performance of classes like HashTable

Override hashCodemethod

If you need to override hashCodethe method, you can refer to the following steps:
1. Take a non-zero constant value and assign it to result. For example, result=17;
2. For each key attribute in the class ( equalsthe attribute used in the method) f, do the following processing
1). Calculate fthe hash value of the attribute and assign it toc

    a. `f`为`boolean`类型,`c = f ? 1 : 0`

    b. `f`为`byte`、`char`、`short`、`int`类型,`c = (int)f`

    c. `f`为`long`类型,`c = (int)(f ^ (f >>> 32))`

    d. `f`为`float`类型,`c = Float.floatToIntBits(f)`

    e. `f`为`double`类型,首先`temp = Double.doubleToLongBits(f)`,之后按照2.1).c步骤来计算`c = (int)(temp ^ (temp >>> 32))`

    f. `f`为对象引用,并且`equals`方法是通过迭代`f`的属性进行判断的,则`hashCode`方法也必须迭代计算`f`中的`hashCode`值。若需要更复杂的计算,则为此属性计算个范式,然后针对这个范式调用`hashCode`。如果属性为`null`,一般返回0
    g. `f`为数组,则需将每一个元素单独按2.1).(a-f)步骤处理,然后按照2.2)将哈希值组合起来。若数组中每个元素都很重要,可以利用`Arrays.hashCode`方法计算
2). 将2.1)中计算的`c`合并到`result`中:`result = 31 * result + c`

3. Backresult

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325950295&siteId=291194637