5

I have such hashmap

HashMap<Man, Double> d = new HashMap<>();

Then I add new pair into it.

d.put(new Man("John"), 5.);

How can I retrieve this pair from this map? I tried to do:

Man man = new Man("John");
System.out.println(d.get(man));

But as a result I have null while I expected 5.

Kenenbek Arzymatov
  • 8,439
  • 19
  • 58
  • 109

3 Answers3

5

This can only work if you override the methods equals(Object obj) and hashCode() in your class Man to allow your HashMap to understand that even if they are not the same instances, they have the same content and should be considered as the same key in your map.

So assuming that your class Man is something like:

public class Man {
    private final String name;

    public Man(final String name) {
        this.name = name;
    }
    ...
}

If you ask your IDE to generate the methods for you, you would get something like this:

@Override
public boolean equals(final Object o) {
    if (this == o) return true;
    if (o == null || this.getClass() != o.getClass()) return false;
    final Man man = (Man) o;
    return Objects.equals(this.name, man.name);
}

@Override
public int hashCode() {
    return Objects.hash(this.name);
}
Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
2

You need to have something unique that defines the object Man. In your case, it appears to be -name.

So you override the equals() method and similarly the hashcode() methods in your Man class using name as the unique identifier.

Since name is a string you can delegate the task to similar methods in the String class.

Ravindra HV
  • 2,558
  • 1
  • 17
  • 26
1

The HashMap is working fine. Just because you make two new objects with the same name, doesn't mean the computer thinks they are the same object.

Try the following:

man1 = new Man("John");
man2 = new Man("John");

if (man1 == man2) {
     System.out.println("Equal");
} else {
    System.out.println("Not equal");
}

You'll get "not equal" because the computer is checking to see if they are exactly the same object, not just named the same.

Each time you're using the "new" keyword, you're declaring a new object and the computer gives it a unique address.

Try this:

man1 = new Man("John");

HashMap<Man, Double> myList = new HashMap<>();
myList.put(man1, "5.00");
System.out.print.ln(myList.get(man1));

you'll see you now get "5.00" back because you're actually giving it the exact object that is the key in the map.

You'll need to define manually how you decide that two "men" are equal if you want the behavior to work like this. You might be better off using a full name as a key, since that's usually going to be unique, and less work for you to implement.

mstorkson
  • 1,130
  • 1
  • 10
  • 26
  • *You'll notice it compiles without error, because the computer recognizes those "Johns" as distinct entities.* What kind of compiler error would be expected here? – shmosel Dec 19 '16 at 20:33
  • Better, but I think `man1.equals(man2)` would be more relevant. This whole answer seems to put undue emphasis on the concept of reference equality, which is out of OP's control, and possibly already understood. – shmosel Dec 19 '16 at 20:45