No, the points will not be correctly handled in a HashSet.
The issue is that hashCode() only uses x, while equals() compares both x and y.
This violates the contract between equals() and hashCode().
1️⃣ Understanding the Problem
Incorrect Point Class
import java.util.HashSet;
import java.util.Set;
class Point {
int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Point point = (Point) obj;
return this.x == point.x && this.y == point.y; // ✅ Compares x and y
}
@Override
public int hashCode() {
return x; // ❌ Only considers x, ignoring y
}
}
public class Main {
public static void main(String[] args) {
Set<Point> set = new HashSet<>();
Point p1 = new Point(3, 5);
Point p2 = new Point(3, 7); // Same x but different y
set.add(p1);
set.add(p2);
System.out.println(set.contains(new Point(3, 5))); // ✅ True
System.out.println(set.contains(new Point(3, 7))); // ❌ False (Wrong behavior)
System.out.println(set.size()); // ❌ Expected: 2, but might be 1 (incorrect behavior)
}
}
2️⃣ Why Is This Wrong?
The hashCode() method only uses x, while equals() compares both x and y.
This means:
- Collisions Happen Unnecessarily
- Every
Pointwith the samexgets the same hash code, even ifyis different. - The
HashSetputs differentPointobjects into the same bucket.
- Every
HashSetMay Not Store Objects Properly- When checking
set.contains(p2), Java:- Finds the bucket based on
hashCode(). - Iterates through the bucket using
equals(). - If an object with the same
xbut differentyis already there,equals()returnsfalse, and the object is lost.
- Finds the bucket based on
- When checking
Example of Collisions
| Object | x | y | hashCode() |
|---|---|---|---|
p1 | 3 | 5 | 3 |
p2 | 3 | 7 | 3 |
📌 Since p1 and p2 have the same hash code (3), they go into the same bucket.
If p1 is stored first, adding p2 fails because equals() says they are different, and the HashSet may discard p2 or fail to retrieve it later.
3️⃣ How to Fix It?
We must ensure that equal objects (equals() == true) always have the same hash code by including both x and y in hashCode().
✅ Fixed Point Class
import java.util.Objects;
class Point {
int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Point point = (Point) obj;
return this.x == point.x && this.y == point.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y); // ✅ Includes both x and y
}
}
🔹 Why Does This Work?
hashCode()now considers bothxandy, ensuring that equal objects have the same hash code.HashSetcan now correctly store and retrieve points.
4️⃣ Verifying the Fix
public class Main {
public static void main(String[] args) {
Set<Point> set = new HashSet<>();
Point p1 = new Point(3, 5);
Point p2 = new Point(3, 7);
set.add(p1);
set.add(p2);
System.out.println(set.contains(new Point(3, 5))); // ✅ True
System.out.println(set.contains(new Point(3, 7))); // ✅ True
System.out.println(set.size()); // ✅ Correctly prints 2
}
}
Now, the HashSet stores both points correctly.
📌 Summary
| Issue | Problem | Fix |
|---|---|---|
HashCode Only Uses x | Different Point objects with the same x have the same hash code, leading to collisions. | Use Objects.hash(x, y) to consider both fields. |
| HashSet Fails to Store/Retrieve Some Points | If two points have the same x but different y, they are placed in the same bucket and might be discarded. | Ensure hashCode() includes all fields used in equals(). |
Violates the equals()–hashCode() Contract | equals() uses x and y, but hashCode() only uses x, causing incorrect behavior in hash-based collections. | Follow the contract: equal objects must have the same hash code. |
✅ Final Best Practices
✔ Always override hashCode() when overriding equals().
✔ Use Objects.hash(x, y) to generate a proper hash code.
✔ Ensure hashCode() includes the same fields as equals().
✔ Test your class in HashSet and HashMap to verify correctness.
By following these rules, your Point class will work correctly and efficiently in Java collections! 🚀