Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

HashMap and equals method overriding

 
Naseem Khan
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi ranchers,
I am facing one problem in retrieving the objects stored in HashMap. It retrurns null. I am overriding equals() method in Car class.

Following code stores (CarObj, OwnerString) as a (key,value) pair in HashMap.I want the name of the owner of some car.



Following line returns true. But map returns null. If both car insances are same, then it must return same owner.



With String it works fine. Is there any other method of Object class I have to override in my case like hashCode().


Thanks & Regards

Naseem
[ May 17, 2006: Message edited by: Naseem Khan ]
 
Christophe Verré
Sheriff
Posts: 14691
16
Eclipse IDE Ubuntu VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The two instances are not the same. There content is equal, but there reference is different.
Mr Burns's car1000, "Mercedes Benz")
Barney's car1000, "Mercedes Benz")

Same brand, same weight, but there are still two different cars.
[ May 17, 2006: Message edited by: Satou kurinosuke ]
 
Naseem Khan
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Quote from Satou kurinosuke

The two instances are not the same. There content is equal, but there reference is different.
Mr Burns's car 1000, "Mercedes Benz")
Barney's car 1000, "Mercedes Benz")

Same brand, same weight, but there are still two different cars.





U mean to say that if u don't have ny handle or reference of ur key object (of some custome class like Car), then u will get null frm Map.

Wat about String

Using String as a key, even If u create a new String by new String("") map gets the value. In that case also String content is same not references.




Wat extra String class has


Thanks

Naseem.K

[ May 17, 2006: Message edited by: Naseem Khan ]

[ May 17, 2006: Message edited by: Naseem Khan ]
[ May 17, 2006: Message edited by: Naseem Khan ]
 
wise owen
Ranch Hand
Posts: 2023
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
HashMap clearly states that it implements the Map interface. The Map interface clearly states that it uses .equals(Object) for object comparison.
HashMap key comparison use equals()
 
Naseem Khan
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If .equals(Object) method is invoked to determine key equality, my equals method returns true.

In K&B book its mentioned that...

1. If .equals(Object) method returns true, then two Objects are same. Same means their contents are same.

2. If == returns true, then two references are same.

Thanks

Naseem
[ May 17, 2006: Message edited by: Naseem Khan ]
 
Henry Wong
author
Marshal
Pie
Posts: 21500
84
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
HashMap also uses the hashcode() method to store the object, if the hashcode is different, then it will be stored incorrectly.

Add this to your Car class...



Henry
 
Firas Zuriekat
Ranch Hand
Posts: 144
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am facing one problem in retrieving the objects stored in HashMap. It retrurns null. I am overriding equals() method in Car class


But you don't have objects really stored! You only have one object stored. So that's why the second object's value is null.

The following works because it has both objects stored:

import java.util.HashMap;
import java.util.Map;

class Car {
private int weight;
private String CarName;
public Car(int weight, String CarName){
this.weight=weight;
this.CarName=CarName;
}

public boolean equals(Object obj) {
Car carObj=null;
if(obj instanceof Car){
carObj=(Car)obj;
}
if(carObj!=null && (this.weight==carObj.weight) && (this.CarName.equals(carObj.CarName))){
return true;
}return false;

}

public static void main(String[] args) {

Map map=new HashMap();
Car myCar=new Car(1000, "Mercedes Benz");
map.put(myCar, "Naseem");
Car neighborCar=new Car(1000, "Mercedes Benz");
map.put(neighborCar, "Naseem's Neighbor");
System.out.println(neighborCar.equals(myCar)); //Line 1
System.out.println(map.get(neighborCar)); //Line 2
}}
[ May 17, 2006: Message edited by: Firas Zureikat ]
 
vivekkumar sharma
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
HI
for Maps remember bucket concept.
when you put any thing into a Map, first its hashcode is looked at to calcualte in which bucket objects shall go.

and in case of reading a map reverse process is followed.First hascode is looked to find bucket and then inside bucket objects ar compared using equals method to find correct object.

ypu have not not overridden hashcode method.Thats why u are not able to retrive correct object,because program does not find correct bucket.
 
Naseem Khan
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Quote from Henry Wong

HashMap also uses the hashcode() method to store the object, if the hashcode is different, then it will be stored incorrectly.

Add this to your Car class...


code:
--------------------------------------------------------------------------------

public int hashCode() { return weight + CarName.hashCode(); }

----------------------------------------------------------------------------






Its really a very gud point u have made. With hashCode implementaion which u have mentioned, map returns ownerName.


String str1=new String("First");
String str2=new String("First");

1. .equals(Object) checks content. It returns true. Fine>>>
2. == operator checks references. Different returns false. Fine>>>
3 boolean b=(str1.hashCode()==str2.hashCode());
here b is set to true.

Wat exactly hashCode() signifies... it returns some int value>>-5647865


Thanks & Regards

Naseem Khan
[ May 17, 2006: Message edited by: Naseem Khan ]
 
Firas Zuriekat
Ranch Hand
Posts: 144
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry I misunderstood the question in my above reply. Actually, you want to use another equivalent key, "myCar", as a key to retrieve the value associated with key "neighborCar". I just mean you want "myCar" to be equal to "neigborCar".

The hashcode calculation for the buckets should be close to that of the equals method (at least as complex).

Since carWeight and carName were tied together in an "&&", then any of these will work:

1) public int hashCode() { return weight * CarName.hashCode(); }
2) public int hashCode() { return weight + CarName.hashCode(); }
3) public int hashCode() { return weight - CarName.hashCode(); }
4) public int hashCode() { return weight / CarName.hashCode(); }

Equals method used 2 things (variables), so hashcode above uses 2 things. The hashcode should be at least as complex as equals to have meaningful equality between objects.
[ May 17, 2006: Message edited by: Firas Zureikat ]
 
Henry Wong
author
Marshal
Pie
Posts: 21500
84
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wat exactly hashCode() signifies... it returns some int value>>-5647865


A hashcode is a single number that represents the object. The hashmap uses it to determine which "bucket" to place the item. Ideally, you want a hashcode formula that gives you as even distribution as possible, so that the hashmap can be used as efficiently as possible.

Doesn't really matter though, as the hashmap will still work, if say, the hashcode that is returned is always zero -- just not very efficient.


In your example, the hashcode return is based on the Object class, which is based on the reference value -- which means that the two cars had different hashcodes. For a hashmap, equal keys must have equal hashcodes, or they will be placed/search in different buckets.

Henry
 
Naseem Khan
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks to all...

Actually there is a joint contract betwen
equals(Object) and hashCode().Both works together.

If two objects are considered equal using .equals(Object) method, then they must have same hashCode value which was not in my case.

regards

Naseem.K
 
Sreeraj Harilal
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
import java.util.HashMap;
import java.util.Map;
class Car {
private int weight;
private String CarName;

public Car(int weight, String CarName){
this.weight=weight;
this.CarName=CarName;
}

public boolean equals(Object obj) {
Car carObj=null;
if(obj instanceof Car){
carObj=(Car)obj;
}
if(carObj!=null && (this.weight==carObj.weight) &&
(this.CarName.equals(carObj.CarName))){
return true;
}
return false;
}

public int hashCode()
{
return 1;
}


public static void main(String[] args) {

Map map=new HashMap();

Car myCar=new Car(1000, "Mercedes Benz");

map.put(myCar, "Naseem");

Car neighborCar=new Car(1000, "Mercedes Benz");

System.out.println(neighborCar.equals(myCar)); //Line 1

System.out.println(map.get(neighborCar)); //Line 2
}
}

Its work fine to ur needs.
Because if u r not override the hashcode method then it uses the Objects hashCode (default) method. Objects hashcode returns the address of the objects.U r created 2 new (using new operator) objects. So the address are different. Map checks hashCode first for comparison then it checks equals.
If hashCode is not equal its will not check the equals method.
 
Naseem Khan
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

public int hashCode()
{
return 1;
}


returning hashCode() value as 1 is not a very gud design becoz in this case, all the objects will land in the same bucket and in that case whole searching operation must be performed by .equals(Object) method.
In Short, Map is not efficient in searching.

Implement hashCode() in such a way that all objects land in different buckets would be a gud design in terms of efficiency of the Map.

Thanks

Naseem.K
 
Sreeraj Harilal
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes u r right.I agree with u.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic