-2

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

  • 5
    Your example code has no duplicate keys. Also, [don't use raw types](https://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it). That's probably what's confusing you. – azurefrog Jan 16 '18 at 21:44
  • 6
    What you think duplicate keys are? `"116"` and `116` are not equal. – tsolakp Jan 16 '18 at 21:44

3 Answers3

1

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.

Zabuzard
  • 25,064
  • 8
  • 58
  • 82
0

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

Ahmad Al-Kurdi
  • 2,248
  • 3
  • 23
  • 39
  • even if they had the same hash code, they would be considered different. – user85421 Jan 16 '18 at 22:02
  • but the hash code is not relevant in this case and there is no reason to show how it is calculated. The way you explained it could be confusing and suggesting that the hash code must be diferent for the keys to be considered diferent. – user85421 Jan 16 '18 at 22:07
0

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)

tevemadar
  • 12,389
  • 3
  • 21
  • 49