Hashmap get(key) returns null even when the value is present

I'm trying to save datas in a hash map and retrieve it. The value corresponding to the key is present and it still returns null. I have implemented the equals() and hashCode() methods also.

ArrayList<Friends> friendsArrayList = new ArrayList<Friends>();
HashMap<Friends,ArrayList<FriendDetails>> friendDetailsHashMap = new HashMap<Friends, ArrayList<FriendDetails>>();
int mSelectedIndex = 0;
...
Friends f = friendsArrayList.get(mSelectedIndex);
ArrayList<MeterGroups> temp2 = friendDetailsHashMap.get(mp); //<== This is where it returns null

My ObjectClass Friends.java:

import java.io.Serializable;

public class Friends implements Serializable {
private String friendName;
private String friendId;
private double distanceFromCurrentLocation;

public Friends(String name, String id)
{
    this.friendName = name;
    this.friendId = id;
    this.distanceFromCurrentLocation = getDistanceFromCurrentLocation();

}

public String getFriendName(){
    return friendName;
}

public void setFriendName(String name){
    this.friendName = name;
}

public void setFriendId(String id){
    this.friendId = id;
}
public String getFriendId(){
    return friendId;
}

public double getDistanceFromCurrentLocation(){
    return 0.0;
}

public int hashCode(){
    return friendName.hashCode()*friendId.hashCode();
}

public boolean equals(Object o){
    if(o == null) {
        return false;
    }
    if(!(o instanceof Friends)) {
        return false;
    }

    Friends other = (Friends) o;
    return this.friendId == other.friendId; //friendId is a unique value
   }
}
Jon Skeet
people
quotationmark

Your equals implementation only uses friendId. Your hashCode implementation uses both friendName and friendId. Therefore there can be two equal objects with different hash codes.

Additionally, you're using == to compare strings within equals, instead of equals. That's comparing references rather than the textual data.

Also, you'll need to handle the possibility that friendId or friendName are null. (So don't just call either equals or hashCode on them unconditionally.) You may well want to use Guava which has methods to help when writing both hashCode and equals.

Finally, you're using a mutable data type as a key in a hash map. That's generally a bad idea - if you add a key to a map and then mutate the object in a way which will affect the hash code, you'll be unable to fetch with the same key later. I would strongly encourage you to use immutable types as map keys.

You need to decide what your equality criteria are, and be consistent between both hashCode and equals. If those two aren't consistent, you may well see issues like this.

people

See more on this question at Stackoverflow