Reputation: 13479
Simple question. I have an object:
class User {
int id;
String username;
public User() {
}
public User(int id, String username) {
this.id = id;
this.username = username;
}
@Override
public String toString() {
return id + " - " + username;
}
@Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + this.id;
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final User other = (User) obj;
return this.id == other.id;
}
public void setUsername(String username) {
this.username = username;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public int getId() {
return id;
}
}
Whose equality is determined based on int id
(it is a database id).
Netbeans auto-generated this hashCode()
method:
@Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + this.id;
return hash;
}
The question is: is there any advantage to this over just returning the (already) unique int id
?
@Override
public int hashCode() {
return id;
}
Collisions are impossible either way.
Right?
Upvotes: 2
Views: 2222
Reputation: 39437
1) You can do:
@Override
public int hashCode() {
return 1; // or any int constant here
}
2)
If you have say 1,000,000 such objects in
the DB, you could maybe do something like:
@Override
public int hashCode() {
return id % 10000;
}
This way you'll have 10000 buckets for 1,000,000 objects.
3) You may turn id
into an Integer
and just do this:
@Override
public int hashCode() {
return id.hashCode();
}
or which is equivalent do:
@Override
public int hashCode() {
return id;
}
1) and 3) are boundary cases for a hashCode implementation.
Approach 2) is somewhere in the middle.
Upvotes: 1
Reputation: 328568
There is a bijection between id
and 31 * 7 + id
so returning id
instead is equivalent. I would therefore simply return id;
and remove unnecessary calculation/complication.
But would that constitute a compliant hashcode method? Let's go back to the javadoc:
The general contract of hashCode is:
- Whenever it is invoked on the same object more than once during an execution of a Java 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 execution 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(java.lang.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.
Does it work in your case?
Upvotes: 0
Reputation: 5451
The Object.hashCode() javadoc tells you everything you need to know to answer your question.
The general contract of hashCode is:
Whenever it is invoked on the same object more than once during an execution of a Java 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 execution 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(java.lang.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.
Upvotes: 1