can i keep duplicate contains of key in Map

Why am i able to keep duplicate contains in Map as key, i had heart about map is : it cat't contains duplicate keys

import java.util.LinkedHashMap;

import java.util.HashMap;

class LinkedHasMapDemo
{
@SuppressWarnings("unchecked")
public static void main(String[] args)
{
    LinkedHashMap l = new LinkedHashMap();
    //{116=kumar, 116=kumar, kumar=kumar, 117=Ram charan, 105=Yash}
    //HashMap l = new HashMap(); 
    //{116=kumar, 117=Ram charan, 116=kumar, kumar=kumar, 105=Yash}
    l.put("116","kumar");       //key is String Object
    l.put(116,"kumar");         //key is Integer Object
    l.put("kumar","kumar");
    l.put(117,"Ram charan");
    l.put(105,"Yash");
    System.out.println(l);  
}
}

but is in this example i am able to keep duplicate keys in the both LinkedHashMap as well as in HashMap

3 answers

  • answered 2018-01-16 21:52 Ahmad Al-Kurdi

    You don't have duplicates. Integer and String objects are not the same type so "116" and 116 are not equals and they have deferent Hash code

    Objects that are equal must have the same hash code within a running process

    in equals method if the type is not equals for both objects, it will return false, please check Integer equals implantation

        public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
    

    also for Hash code they will not be equals in your case :

    how String hash code is calculated :

     public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;
    
            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }
    

    And for Integer hash code is it the same integer value so in your case it will be 116 for Integer instance, so those will never be the same.

    please avoid raw-types, that is using HashMap without specifying the generic type, please read this article what-is-a-raw-type-and-why-shouldnt-we-use-it for more details

  • answered 2018-01-16 22:05 Zabuza

    You are right, a Map does not hold duplicate keys (this only applies to keys, values can be equal). If you put a value under an already added key the previous value will be overridden. Therefore consider the following example:

    HashMap<String, Integer> map = new HashMap<>();
    
    map.put("key", 1);
    System.out.println(map.get("key")); // Outputs 1
    System.out.println(map.size()); // Outputs 1
    
    map.put("key", 2);
    System.out.println(map.get("key")); // Outputs 2
    System.out.println(map.size()); // Still outputs 1
    

    The problem with your counter-example is that you actually don't have duplicates in your map.

    You put 116 (an int or Integer after boxing) and "116" (a String). Since both are of different type the map differentiates them, they are different objects. Consider the following example

    HashMap<Object, Integer> map = new HashMap<>();
    
    map.put("116", 1);
    System.out.println(map.size()); // Outputs 1
    
    map.put(116, 2);
    System.out.println(map.size()); // Now outputs 2
    
    System.out.println("116".equals(116)); // Outputs false
    

    In general you should never use raw-types, that is using HashMap without specifying the generic type to use, like HashMap<String, Integer>. If you don't specify anything it will use HashMap<Object, Object>. By that it allows every Object to be put into the map. In many cases you can and want to restrict this to a specific type only.

  • answered 2018-01-16 22:14 tevemadar

    Try the following:

    String s123="123";
    Integer i123=123;
    System.out.println(s123.hashCode());
    System.out.println(i123.hashCode());
    System.out.println(i123.equals(s123)); // you can try s123.equals(i123) too
    

    You can even test it online, just copy/type these lines to http://www.javarepl.com/term.html - you will see that the String has a hashcode of 48690, the Integer has 123, and they do not consider equal to each other.
    (Of course it works with 116 too just I did not have that number in front of me while typing this answer)