Method hashCode() in Java

What is the hashCode() method for

The hashCode() method is required to calculate the hash code of the object passed as an input parameter. In Java, it is an integer, in a broader sense, a fixed-length bit string obtained from an array of arbitrary length. This method is implemented in such a way that for the same input object, the hash code will always be the same. It should be understood that in Java the set of possible hash codes is limited to the int type, and the set of objects is not limited by anything. Because of this, it is quite possible that the hash codes of different objects may coincide:

  • if the hash codes are different, then the objects are guaranteed to be different;
  • if the hash codes are equal, then the objects may not necessarily be equal.

Rules for overriding the Object.hashCode() method. Is there any guidance on what fields to use when counting hashCode()?

General advice: choose fields that are likely to be different. To do this, you must use unique, best of all primitive fields, such as id, uuid. In this case, you need to follow the rule, if the fields are involved in the calculation of hashCode(), then they must be involved in the execution of equals().

Can different objects have the same hashCode()?

Yes they can. The hashCode() method does not guarantee that the return value is unique. The situation when different objects have the same hash codes is called a collision. The likelihood of a collision depends on the hash code generation algorithm used.

If the class Point{int x, y;} implements method equals(Object that) {(return this.x == that.x && this.y == that.y)}, but make the hash code as int hashCode() {return x;}, then will such points be placed and retrieved from the HashSet correctly?

HashSet uses HashMap to store items. When adding an element to the HashMap, a hash code is calculated, which determines the position in the array where the new element will be inserted. For all instances of the Point class, the hash code will be the same for all objects with the same x, which will lead to the degeneration of the hash table into a list.

When a collision occurs in the HashMap, it checks for the presence of an element in the list: e.hash == hash && ((k = e.key) == key || key.equals(k)). If the element is found, then its value is overwritten. In our case, the equals() method will return false for different objects. Accordingly, the new element will be successfully added to the HashSet. The item will also be retrieved successfully. But the performance of such code will be low and the advantages of hash tables will not be used.

Can different objects (ref0 != ref1) have ref0.equals(ref1) == true?

Yes they can. To do this, the equals() method must be overridden in the class of these objects.

If the Object.equals() method is used, then for two references x and y, the method will return true if and only if both references point to the same object (i.e., x == y returns true).

Can different references to the same object (ref0 == ref1) have ref0.equals(ref1) == false?

In general, they can, if the equals() method is implemented incorrectly and does not fulfill the reflexivity property: for any non-null references x, the x.equals(x) method must return true.

Is it possible to implement the equals(Object that) {return this.hashCode() == that.hashCode()} method like this?

Strictly speaking, it is impossible, since the hashCode() method does not guarantee the uniqueness of the value for each object. However, for comparing instances of the Object class, such code is acceptable, since the hashCode() method in the Object class returns unique values for different objects (its calculation is based on using the object's memory address).

Equals() requires you to check that the equals(Object that) argument is of the same type as the object itself. What is the difference between this.getClass() == that.getClass() and that instanceof MyClass?

The instanceof operator compares the object and the specified type. It can be used to check if a given object is an instance of some class, or an instance of its child class, or an instance of a class that implements the specified interface.

this.getClass() == that.getClass() checks two classes for identity, so to implement the equals() method contract correctly, you must use an exact comparison using the getClass() method.

Is it possible to implement the equals() method of MyClass like this: class MyClass {public boolean equals (MyClass that) {return this == that;}}?

It can be implemented, but this method does not override the equals() method of the Object class, but overloads it.

There is a class Point{int x, y;}. Why is the hash code 31 * x + y preferred over x + y?

The multiplier creates a dependence of the hash code value on the order in which the fields are processed, which ultimately generates the best hash function.


Read also:


Comments

Popular posts from this blog

Methods for reading XML in Java

XML, well-formed XML and valid XML

ArrayList and LinkedList in Java, memory usage and speed