Could someone explain the following behavior for .hashcode().
When working with the two classes below I get different values for .hashcode() calls. Now I am just trying to understand the reason behind this behavior. I'm working with the default implementation of .hashcode(). I am not overriding it nor do I want to use it for hashtables or hashmaps. ( I understand this is the one of the main reasons for hashcodes)
If I execute Main 10 times I would get the same value for contact3 hashcode. hashcode = 1555009629 in this case.
Now... If I execute the same Main 10 other times but comment out the call to hashcode in mergeContactData then the hashcode value in Main for contact3 would change to 41359092.
The two following questions talk about overriding hashcode() and explanations using maps and tables which is not the intended use for this question. This question simply about behavior of default implementation.
Reason behind JVM's default Object.HashCode() implementation
Why do I need to override the equals and hashCode methods in Java?
public class Main {
public static void main(String[] args) {
Contact contact = new Contact("Gustavo", "xxx", 5555555555L);
Contact contact2 = new Contact("Gustavo", "xxx", 5555555555L);
Contact contact3 = contact.mergeContactData(contact2);
System.out.println("Hashcode for contact3: " + contact3.hashCode());
}
}
import java.util.HashSet;
import java.util.Set;
public class Contact {
private String name;
private Set<String> emails = new HashSet<String>();
private Set<String> phones = new HashSet<>();
public Contact(String name) {
this(name, null, 0);
}
public Contact(String name, String email) {
this(name, email, 0);
}
public Contact(String name, long phone) {
this(name, null, phone);
}
public Contact(String name, String email, long phone) {
this.name = name;
if (email != null) {
this.emails.add((email));
}
if (phone < 1000000000) {
System.out.println("Invalid Phone Number");
return;
}
String phoneNumber = "";
phoneNumber += "(" +
String.valueOf(phone / 10000000);
phone = phone % 10000000;
phoneNumber += ")" + String.valueOf(phone / 10000);
phone = phone % 10000;
phoneNumber += "-" + String.valueOf(phone);
this.phones.add(phoneNumber);
}
public String getName() {
return this.name;
}
public Contact mergeContactData(Contact contact) {
if (this.name.equals(contact.name)) {
Contact newContact = new Contact(this.name);
newContact.emails.addAll(this.emails);
newContact.phones.addAll(this.phones);
newContact.emails.addAll(contact.emails);
System.out.println(newContact.hashCode());
contact.phones.forEach(s -> newContact.phones.add(s));
return newContact;
} else {
System.out.println("Not the same contact name");
return this;
}
}
@Override
public String toString() {
return this.name + " -> emails: " + this.emails + " Phone: " + this.phones;
}
}
hashCode(), so it is using the implementation fromObject, which is returning a fixed value per instance. The hashcode is different every time you run your program. Printing the hash code does not matter, the value is different simply because you are executing the program multiple times.Object.hashCode()depends on the actual JVM you are using. I can confirm what you see withOpenJDK Runtime Environment 17.0.13_p11 (build 17.0.13+11)on a linux machine, but that doesn't mean that thehashCode()has to work that way everywhere, only what is defined on docs.oracle.com/javase/8/docs/api/java/lang/….java.lang.Objectis calculated.