• A superclass
has already overridden equals, and the superclass behavior

is appropriate
for this class.

• The class is
private or package-private, and you are certain that its equals method will
never be invoked.

One kind of
value class that does not require the equals method to be overridden is a class
that uses instance control(Singleton) to ensure that at most one object exists
with each value. Enum types fall into this category. For these classes, logical
equality is the same as object identity, so Object’s equals method functions as
a logical equals method.

When
is it appropriate to override Object.equals?

When a class
has a notion of logical equality that differs from mere object identity and a
superclass has not already overridden equals to implement the desired behavior.

Not only is
overriding the equals method necessary to satisfy programmer expectations; it
enables instances to serve as map keys or set elements with predictable,
desirable behavior.

1. Use the ==
operator to check if the argument is a reference to this object.

If so, return
true. This is just a performance optimization, but one that is worth doing if
the comparison is potentially expensive.

2. Use the
instanceof operator to check if the argument has the correct type.

If not, return
false. Typically, the correct type is the class in which the method occurs.
Occasionally, it is some interface implemented by this class.

3. Cast the
argument to the correct type.

4. For each “significant”
field in the class, check if that field of the argument matches the corresponding
field of this object.

For primitive
fields whose type is not float or double, use the == operator for comparisons;
for object reference fields, invoke the equals method recursive-

ly; for float
fields, use the Float.compare method; and for double fields, use

Double.compare.

5. When you are
finished writing your equals method, ask yourself three questions: Is it
symmetric? Is it transitive? Is it consistent? And don’t just ask yourself;
write unit tests to check that these properties hold! If they don’t, figure out
why not, and modify the equals method accordingly

• Always override hashCode when you override equals

• Don’t substitute another type for Object in the equals declaration.

You must
override hashCode in every class that overrides equals. Failure to do so will
result in a violation of the general contract for Object.hashCode, which will prevent
your class from functioning properly in conjunction with all hash-based collections,
including HashMap, HashSet, and Hashtable.

Here is the
contract, copied from the Object specification [JavaSE6]:

• Whenever it is invoked on the same object more than once during an
execution of an application, the hashCode method must consistently return the same
integer, provided no information used in equals comparisons on the object is
modified. This integer need not remain consistent from one execu-

tion of an
application to another execution of the same application.

• If two objects are equal according to the equals(Object) method, then
calling the hashCode method on each of the two objects must produce the same integer
result.

• It is not required that if two objects are unequal according to the
equals(Object) method, then calling the hashCode method on each of the two
objects must produce distinct integer results. However, the programmer should
be aware that producing distinct integer results for unequal objects may
improve the performance of hash tables.

Equal
objects must have equal hash codes.

Objects
with equal hashcode is not required to be equal.

What
would happen if 2 equals object have different hashcode? CRUDJ

2 equals
object would be insert into same hashmap, we can query it and delete it.

Map m = new
HashMap();

m.put(new PhoneNumber(707,
867, 5309), “Jenny”);

// return null

System.err.println(m.get(new PhoneNumber(707,
867, 5309)));

// return false

System.err.println(m.containsKey(new PhoneNumber(707,
867, 5309)));

m.put(new PhoneNumber(707,
867, 5309), “Jenny”);

System.err.println(m.size());
// return 2

m.remove(“Jenny”);

System.err.println(m.size()); // return 2

The get method
is likely to look for the phone number in a different hash bucket from the one
in which it was stored by the put method. Even if the two instances happen to
hash to the same bucket, the get method will almost certainly return null, as
HashMap has an optimization that caches the hash code associated with each
entry and doesn’t bother checking for object equality if the hash codes don’t
match.

What
if 2 un-equal objects have same hashcode?

This would
decrease hashset. hashmap performance.

// The worst
possible legal hash function - never use!

@Override
public int hashCode() { return 42; }

Hash tables
degenerate to linked lists.

A good hash
function tends to produce unequal hash codes for unequal objects.

Ideally, a hash
function should distribute any reasonable collection of unequal instances
uniformly across all possible hash values.

Do not be
tempted to exclude significant parts of an object from the hash code
computation to improve performance.

If equal
instances have unequal hash codes, figure out why and fix the problem.

You must
exclude any fields that are not used in equals comparisons, or you risk
violating the second provision of the hashCode contract.

The multiplication
in step 2.b makes the result depend on the order of the fields, yielding a much
better hash function if the class has multiple similar fields.

The
multiplication in step 2.b makes the result depend on the order of the fields,
yielding a much better hash function if the class has multiple similar fields.

For example, if
the multiplication were omitted from a String hash function, all anagrams would
have identical hash codes. The value 31 was chosen because it is an odd prime.
If it were even and the multiplication overflowed, information would be lost,
as multiplication by 2 is equivalent to shifting. The advantage of using a
prime is less clear, but it is traditional. A nice property of 31 is that the multiplication
can be replaced by a shift and a subtraction for better performance:

31*i==(i<<5)-i.
Modern VMs do this sort of optimization automatically.