A Java Interview Code Output Question about hash collision

Serdar A.
6 min readMar 17, 2024

--

Hello everyone;

Firstly, look at the given object and its test class below and what is the output?

public class MyObject {

private String text;
private int val;

public MyObject(String text,int val) {
this.text = text;
this.val = val;
}

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}

public int getVal() {
return val;
}

public void setVal(int val) {
this.val = val;
}

@Override
public boolean equals(Object obj) {

if(this == obj)
{
return true;
}

if(obj == null)
{
return false;
}

if(getClass() != obj.getClass())
{
return false;
}

MyObject other = (MyObject) obj;

if(val != other.val)
{
return false;
}

if(text == null && other.text != null)
{
return false;
}
else if(!text.equals(other.text))
{
return false;
}
return true;
}

@Override
public int hashCode() {

final int primeNum = 29;
int result = 1;
result = primeNum * result + val;
result = primeNum * result + ((text == null) ? 0 : text.hashCode());

return result;
}
}
public class Test {

public static void main(String[] args) {

Map<MyObject,Integer> map = new HashMap();

MyObject obj1 = new MyObject("a",100);
MyObject obj2 = new MyObject("a",100);
MyObject obj3 = new MyObject("b",200);
MyObject obj4 = obj3;

map.put(obj1,10);
map.put(obj2,20);
map.put(obj3,30);
map.put(obj4,40);

System.out.println("obj1.equals(obj2) :" + obj1.equals(obj2));
System.out.println("obj3.equals(obj4) :" + obj3.equals(obj4));

System.out.println("map size : " + map.size());

System.out.println("map.get(obj1) : " + map.get(obj1));
System.out.println("map.get(obj2) : " + map.get(obj2));
System.out.println("map.get(obj3) : " + map.get(obj3));
System.out.println("map.get(obj4) : " + map.get(obj4));
}
}
wait

Output is :


obj1.equals(obj2) :true
obj3.equals(obj4) :true
map size : 2
map.get(obj1) : 20
map.get(obj2) : 20
map.get(obj3) : 40
map.get(obj4) : 40

map size 2. Value of obj1 was replaced by value of obj2.

Let’s go step by step to understand how this happens.

  1. Can not implement equals() and hashcode() method in MyObject class
public class MyObject {

private String text;
private int val;

public MyObject(String text,int val) {
this.text = text;
this.val = val;
}

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}

public int getVal() {
return val;
}

public void setVal(int val) {
this.val = val;
}
}
public class Test1 {

public static void main(String[] args) {

Map<MyObject,Integer> map = new HashMap();

MyObject obj1 = new MyObject("a",100);
MyObject obj2 = new MyObject("a",100);
MyObject obj3 = new MyObject("b",200);
MyObject obj4 = obj3;

map.put(obj1,10);
map.put(obj2,20);
map.put(obj3,30);
map.put(obj4,40);

System.out.println("obj1.hashCode() :" + obj1.hashCode()); //default hashCode method
System.out.println("obj2.hashCode() :" + obj2.hashCode()); //default hashCode method
System.out.println("obj3.hashCode() :" + obj3.hashCode()); //default hashCode method
System.out.println("obj4.hashCode() :" + obj4.hashCode()); //default hashCode method

System.out.println("obj1.equals(obj2) :" + obj1.equals(obj2)); // default equals method
System.out.println("obj3.equals(obj4) :" + obj3.equals(obj4)); // default equals method

System.out.println("map size : " + map.size());

System.out.println("map.get(obj1) : " + map.get(obj1));
System.out.println("map.get(obj2) : " + map.get(obj2));
System.out.println("map.get(obj3) : " + map.get(obj3));
System.out.println("map.get(obj4) : " + map.get(obj4));
}
}

Output is :

obj1.hashCode() :1705736037
obj2.hashCode() :455659002
obj3.hashCode() :250421012
obj4.hashCode() :250421012
obj1.equals(obj2) :false
obj3.equals(obj4) :true
map size : 3
map.get(obj1) : 10
map.get(obj2) : 20
map.get(obj3) : 40
map.get(obj4) : 40

Set same value for obj1 and obj2 instance but we use new keyword and create two different object with different references. So obj1 and obj2 object not equals. obj3 assigned to obj4 and obj3 and obj4 are pointing same reference and value of obj3 was repleced with value of obj4. Finally hashmap size is 3.

2. Override only equals() method

public class MyObject {

private String text;
private int val;

public MyObject (String text,int val) {
this.text = text;
this.val = val;
}

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}

public int getVal() {
return val;
}

public void setVal(int val) {
this.val = val;
}

@Override
public boolean equals(Object obj) {

if(this == obj)
{
return true;
}

if(obj == null)
{
return false;
}

if(getClass() != obj.getClass())
{
return false;
}

MyObject other = (MyObject) obj;

if(val != other.val)
{
return false;
}

if(text == null && other.text != null)
{
return false;
}
else if(!text.equals(other.text))
{
return false;
}
return true;
}
}
public class Test {

public static void main(String[] args) {

Map<MyObject,Integer> map = new HashMap();

MyObject obj1 = new MyObject("a",100);
MyObject obj2 = new MyObject("a",100);
MyObject obj3 = new MyObject("b",200);
MyObject obj4 = obj3;

map.put(obj1,10);
map.put(obj2,20);
map.put(obj3,30);
map.put(obj4,40);

System.out.println("obj1.hashCode() :" + obj1.hashCode()); //default hashCode method
System.out.println("obj2.hashCode() :" + obj2.hashCode()); //default hashCode method
System.out.println("obj3.hashCode() :" + obj3.hashCode()); //default hashCode method
System.out.println("obj4.hashCode() :" + obj4.hashCode()); //default hashCode method

System.out.println("obj1.equals(obj2) :" + obj1.equals(obj2)); // override equals method
System.out.println("obj3.equals(obj4) :" + obj3.equals(obj4)); // override equals method

System.out.println("map size : " + map.size());

System.out.println("map.get(obj1) : " + map.get(obj1));
System.out.println("map.get(obj2) : " + map.get(obj2));
System.out.println("map.get(obj3) : " + map.get(obj3));
System.out.println("map.get(obj4) : " + map.get(obj4));
}
}

Output is :

obj1.hashCode() :1705736037
obj2.hashCode() :455659002
obj3.hashCode() :250421012
obj4.hashCode() :250421012
obj1.equals(obj2) :true
obj3.equals(obj4) :true
map size : 3
map.get(obj1) : 10
map.get(obj2) : 20
map.get(obj3) : 40
map.get(obj4) : 40

According to equals() method, obj1 and obj2 instance are equal. But different hashcode.

3. Override only hashcode() method

public class MyObject {

private String text;
private int val;

public MyObject(String text,int val) {
this.text = text;
this.val = val;
}

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}

public int getVal() {
return val;
}

public void setVal(int val) {
this.val = val;
}

@Override
public int hashCode() {

final int primeNum = 29;
int result = 1;
result = primeNum * result + val;
result = primeNum * result + ((text == null) ? 0 : text.hashCode());

return result;
}
}
public class Test {

public static void main(String[] args) {

Map<MyObject,Integer> map = new HashMap();

MyObject obj1 = new MyObject("a",100);
MyObject obj2 = new MyObject("a",100);
MyObject obj3 = new MyObject("b",200);
MyObject obj4 = obj3;

map.put(obj1,10);
map.put(obj2,20);
map.put(obj3,30);
map.put(obj4,40);

System.out.println("obj1.hashCode() :" + obj1.hashCode()); //override hashCode method
System.out.println("obj2.hashCode() :" + obj2.hashCode()); //override hashCode method
System.out.println("obj3.hashCode() :" + obj3.hashCode()); //override hashCode method
System.out.println("obj4.hashCode() :" + obj4.hashCode()); //override hashCode method

System.out.println("obj1.equals(obj2) :" + obj1.equals(obj2)); // default equals method
System.out.println("obj3.equals(obj4) :" + obj3.equals(obj4)); // default equals method

System.out.println("map size : " + map.size());

System.out.println("map.get(obj1) : " + map.get(obj1));
System.out.println("map.get(obj2) : " + map.get(obj2));
System.out.println("map.get(obj3) : " + map.get(obj3));
System.out.println("map.get(obj4) : " + map.get(obj4));
}
}

Output is :

obj1.hashCode() :3838
obj2.hashCode() :3838
obj3.hashCode() :6739
obj4.hashCode() :6739
obj1.equals(obj2) :false
obj3.equals(obj4) :true
map size : 3
map.get(obj1) : 10
map.get(obj2) : 20
map.get(obj3) : 40
map.get(obj4) : 40

According to hashCode() method, hashCodes of obj1 and obj2 is same but they are different references (object’s equals)

4. Override equals() and hashCode() methods

public class MyObject {

private String text;
private int val;

public MyObject(String text,int val) {
this.text = text;
this.val = val;
}

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}

public int getVal() {
return val;
}

public void setVal(int val) {
this.val = val;
}

@Override
public boolean equals(Object obj) {

if(this == obj)
{
return true;
}

if(obj == null)
{
return false;
}

if(getClass() != obj.getClass())
{
return false;
}

MyObject other = (MyObject) obj;

if(val != other.val)
{
return false;
}

if(text == null && other.text != null)
{
return false;
}
else if(!text.equals(other.text))
{
return false;
}
return true;
}

@Override
public int hashCode() {

final int primeNum = 29;
int result = 1;
result = primeNum * result + val;
result = primeNum * result + ((text == null) ? 0 : text.hashCode());

return result;
}
}
public class Test {

public static void main(String[] args) {

Map<MyObject,Integer> map = new HashMap();

MyObject obj1 = new MyObject("a",100);
MyObject obj2 = new MyObject("a",100);
MyObject obj3 = new MyObject("b",200);
MyObject obj4 = obj3;

map.put(obj1,10);
map.put(obj2,20);
map.put(obj3,30);
map.put(obj4,40);

System.out.println("obj1.hashCode() :" + obj1.hashCode()); //override hashCode method
System.out.println("obj2.hashCode() :" + obj2.hashCode()); //override hashCode method
System.out.println("obj3.hashCode() :" + obj3.hashCode()); //override hashCode method
System.out.println("obj4.hashCode() :" + obj4.hashCode()); //override hashCode method

System.out.println("obj1.equals(obj2) :" + obj1.equals(obj2)); // override equals method
System.out.println("obj3.equals(obj4) :" + obj3.equals(obj4)); // override equals method

System.out.println("map size : " + map.size());

System.out.println("map.get(obj1) : " + map.get(obj1));
System.out.println("map.get(obj2) : " + map.get(obj2));
System.out.println("map.get(obj3) : " + map.get(obj3));
System.out.println("map.get(obj4) : " + map.get(obj4));
}
}

Output is :

obj1.hashCode() :3838
obj2.hashCode() :3838
obj3.hashCode() :6739
obj4.hashCode() :6739
obj1.equals(obj2) :true
obj3.equals(obj4) :true
map size : 2
map.get(obj1) : 20
map.get(obj2) : 20
map.get(obj3) : 40
map.get(obj4) : 40

According to equals() method, obj1 and obj2 are equal. At the same time, their hashcode are same. Value of obj1 was replaced with value of obj2. Finally hashmap size 2.

Thanx to reading

--

--

Serdar A.
Serdar A.

Written by Serdar A.

Senior Software Developer & Architect at Havelsan Github: https://github.com/serdaralkancode #Java & #Spring & #BigData & #React & #Microservice

No responses yet