Free tools Windows power users keep installed
One-click scans. No signup required.
In Java, == on object references asks whether two references point to the same object. equals() asks whether objects are logically equal—but only if their class defines that meaning. The distinction matters when comparing values, using objects as map keys or set elements, and working with nullable references.
What does == mean for objects?
For object references, == compares identity: it returns true only when both references designate the same object. It does not inspect the objects’ fields. Oracle’s Object API defines the default equals implementation in the same identity-based way.
String first = new String("Java");
String second = new String("Java");
System.out.println(first == second); // false
The two references above point to separate objects, so == is false even though their contents match. Use == when identity itself is what matters—for example, to check whether a reference is null, or whether two references designate the very same object.
What does equals() compare?
equals() can express logical or value equality: whether two objects contain equivalent information. The Object implementation does not provide that behavior automatically; it returns true only for the same object. A class must override equals() to define value-based comparison. Oracle’s Object methods tutorial illustrates this with distinct Book objects compared by ISBN.
String first = new String("Java");
String second = new String("Java");
System.out.println(first.equals(second)); // true
Here, String defines equality by content, so two different objects can be equal. For a class that does not override equals(), calling it still has the default identity-based meaning.
How to implement equals() correctly
The Java API requires equality implementations to obey a contract. For non-null references x, y, and z:
Rank #2
- Reflexive:
x.equals(x)is true. - Symmetric: if
x.equals(y)is true, theny.equals(x)is true. - Transitive: if
x.equals(y)andy.equals(z)are true, thenx.equals(z)is true. - Consistent: repeated comparisons return the same result while the state used for comparison has not changed.
- Null-safe by contract:
x.equals(null)returns false.
A typical implementation first handles the same-reference and wrong-type cases, then compares the fields that define equality. The exact fields are a design decision: use the state that makes two instances interchangeable for the class’s intended meaning, not every field indiscriminately.
import java.util.Objects;
final class Book {
private final String isbn;
Book(String isbn) {
this.isbn = isbn;
}
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (!(other instanceof Book)) return false;
Book book = (Book) other;
return Objects.equals(isbn, book.isbn);
}
@Override
public int hashCode() {
return Objects.hash(isbn);
}
}
This example treats books with equal ISBN values as equal and handles a possibly-null ISBN. In production, choose equality fields in line with the class’s domain and inheritance design; equality across a class hierarchy can be difficult to keep symmetric.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Why equals() and hashCode() belong together
If two objects are equal according to equals(), they must return the same hashCode(). The reverse is not required: unequal objects are allowed to have the same hash code. Collisions are valid, though excessive collisions can reduce hash-table performance. Oracle documents this contract in the Object API.
This rule is essential for hash-based collections such as HashMap and HashSet. They use a hash code to find a candidate location, then equality to distinguish keys or elements. If a class overrides equals() but retains an identity-based hashCode(), logically equal objects may be placed in different locations and collection lookups can fail unexpectedly. Implement both methods using the same equality-defining fields.
Rank #4
Objects.hash(...) can combine multiple values when implementing a hash code. It is a convenience, not a requirement; any implementation is valid if it satisfies the equal-objects/same-hash-code rule.
How to compare nullable references
Calling a.equals(b) throws NullPointerException if a is null. For a comparison where either reference may be null, use Objects.equals(a, b):
Best Value
import java.util.Objects;
Objects.equals(a, b)
The result is true when both references are null, false when exactly one is null, and otherwise the result of calling a.equals(b). This behavior is specified by the Objects API. The helper does not change the equality rules of either object’s class.
When identity equality is intentional
Use IdentityHashMap only for identity-based keys
Ordinary maps rely on key equality and hash codes. IdentityHashMap is a specialized exception: its documentation says keys are considered equal exactly when k1 == k2, rather than when k1.equals(k2). It is explicitly not a general-purpose Map. Use it only when the identity of the key object is the intended distinction.
Avoid identity-sensitive operations on value-based classes
Some Java classes are designated value-based: their equality, hash code, and string representation are derived from state, and equal instances are intended to be interchangeable. Oracle’s value-based classes guidance advises against identity-sensitive operations on these objects, including using ==, identity hash codes, or synchronization. Such operations can have unpredictable results for value-based instances; compare them by value instead.
Which comparison should you use?
| Situation | Use | What it means |
|---|---|---|
| Check whether a reference is null | value == null |
Tests whether the reference points to no object. |
| Check whether two references point to the same object | a == b |
Tests object identity. |
| Compare object values or logical state | a.equals(b) |
Uses the class’s equality definition; the call requires a non-null receiver. |
| Compare values when either reference may be null | Objects.equals(a, b) |
Handles nulls, then delegates to the non-null first argument’s equals(). |
| Use keys with ordinary hash-based maps or sets | Consistent equals() and hashCode() |
Equal keys or elements must have matching hash codes. |
| Use object identity as the map-key distinction | IdentityHashMap |
Keys match only when their references are identical. |
What mutability changes
Fields used by equals() and hashCode() determine an object’s logical equality and hash location. If those fields change while an object is stored as a key in a HashMap or as an element in a HashSet, later lookups may no longer find it where the collection placed it. Prefer immutable equality-defining state for objects used in hash-based collections, or avoid changing that state while the object is stored there.
Recommended Free Tools
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

