哈希码与equals方法的对比及如何用.equals方法比较哈希码
Hey folks! Let's dive into the key differences between hashCode() and equals()—two methods absolutely critical for working with objects in Java (and many OOP languages) but often mixed up. I'll also cover when and how you might use equals() to compare hash codes, though that's a less common scenario.
- Core Purpose
hashCode(): Generates an integer "hash value" for an object, designed to enable fast lookups in hash-based collections likeHashMap,HashSet, orHashTable. It’s all about performance for storage and retrieval.equals(): Determines if two objects are logically equal (not just the same memory reference). For example, twoUserobjects with the sameidandemailmight be considered equal even if they’re separate instances.
- Return Type
hashCode()returns a primitiveint.equals()returns aboolean.
- Performance
hashCode()is a lightweight calculation (typically based on object fields) meant to be fast.equals()is often more expensive, as it may need to compare multiple fields (strings, numbers, nested objects) to determine equality.
- Contract Rules (The Golden Rule)
- If
a.equals(b)returnstrue, thena.hashCode()must equalb.hashCode(). Breaking this will break hash-based collections (e.g., two equal objects might end up in different buckets of aHashMap). - The reverse isn’t true: Same hash codes don’t guarantee equal objects (this is called a hash collision—different objects can produce the same integer hash value).
- If
- Default Object Class Behavior
- The base
Objectclass’sequals()checks if two references point to the exact same memory address (equivalent to using==). - The default
hashCode()generates a value based on the object’s memory address. - Critical Note: If you override
equals()to define logical equality (e.g., comparing object fields), you must overridehashCode()too. Failing to do so violates the contract and leads to unpredictable behavior in collections.
- The base
.equals() to Compare Hash Codes First, let’s clarify: Hash codes are primitive int values, so most of the time you’ll just use == to compare them directly. But if you’ve wrapped the hash code in an Integer object (e.g., storing hash codes in a collection like ArrayList<Integer>), using equals() is the safe way to compare their underlying values.
Here’s a practical example:
// Get hash codes as primitives from two objects int hash1 = customerA.hashCode(); int hash2 = customerB.hashCode(); // Direct primitive comparison (most common use case) boolean hasMatchingHash = hash1 == hash2; // If hash codes are wrapped in Integer objects Integer hashObj1 = hash1; Integer hashObj2 = hash2; // Use equals() to compare the actual integer values (avoids reference comparison pitfalls) boolean hasMatchingHashObj = hashObj1.equals(hashObj2);
Why does this matter? For Integer objects outside the cached range (-128 to 127), using == compares object references instead of their integer values. equals() bypasses this by explicitly checking the underlying int value inside the wrapper.
Important Caveat
Even if two hash codes match (whether via == or equals()), you can’t assume the original objects are equal. Hash collisions are possible—different objects can generate the same hash code. Always use the equals() method on the objects themselves to confirm logical equality.
内容的提问来源于stack exchange,提问作者MasterTolboll

