0
import java.util.*;

class U {
    int x;

    U(int x) {
        this.x = x;
    }
}

public class G {
    public U a = new U(22);
    public U b = new U(23);
    Integer y = 22;
    Integer r = 23;

    void a() {
        Map<U, Integer> set = new HashMap<U, Integer>();
        set.put(a, y);
        set.put(a, r);
        set.put(b, y);
        System.out.print(set.size() + " ");
    }

    public static void main(String[] args) {
        G m = new G();
        m.a();
    }
}

I always get confused in Maps and Lists. I know that when map put keys in the collection , it calls hashcode and if the bucket is same , equal method is called. However , I learned that if the class override these two methods then only duplicate keys are not stored. For example wrapper class : String implements its own hashcode and equal method. Moreover, if you don't do so, a unique hashcode is been called and duplicate keys get stored in the collection.

But in the above example , class U is NOT implementing hashcode and equal method. However , Map is not allowing duplicate keys.

I checked the SIZE : its 2 its supposed to be 3 because my U class is not implementing either hashcode nor equal.

please clear me

Thanks in advance

jmj
  • 237,923
  • 42
  • 401
  • 438
user2985842
  • 437
  • 9
  • 24

4 Answers4

7

HashMap doesn't allow duplicated keys,

If you don't provide hashcode() and equals() implementation it extends it from super class (for your case it is java.lang.Object), and that implementation provides same hashcode for same object and equals() on same object returns true

public boolean equals(Object obj) {
    return (this == obj);
}

as well

jmj
  • 237,923
  • 42
  • 401
  • 438
1

You are using the same instance of U as a key twice:

set.put(a, y);
set.put(a, r);

Your U class does not implement hashCode() as you mention, so the default implementation is Object#hashCode which will obviously be the same since it is the same instance. Therefore the map will only contain the second entry. However, if you try the following you would end up with two separate entries:

set.put(new U(22), y);
set.put(new U(22), r);

But generally you will always want to implement equals() and hashCode() for any class used as the key of a map - otherwise you can't look up the value without having access to the exact instance it was stored as!

andersschuller
  • 13,509
  • 2
  • 42
  • 33
  • This might be a dumb question, but wouldn't it sort of defeat the purpose to add something to a HashMap without having a reference to access it? – C.B. Mar 25 '14 at 19:58
  • @C.B. You generally want to use keys that are equal not by identity, but by their contents. Think of using a String as a key: if a String's hashCode was completely unique to each instance, you would have to keep track of the exact instance stored in the map. But because all Strings that contain the same characters have the same hashCode, you can look it up using any equivalent String instance. – andersschuller Mar 25 '14 at 20:02
0

By design hashmaps do not add duplicate keys. It will replace the value of the current item in the map with that key. See http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put%28K,%20V%29

bastijn
  • 5,841
  • 5
  • 27
  • 43
0

If you want to add duplicate keys, try something like this:

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

    map.put(1, new ArrayList<Integer>());
    map.get(1).add(1);
    map.get(1).add(2);
Klemens Morbe
  • 595
  • 9
  • 24