0

I have a HashMap as below (assuming it has 10,0000 elements)

HashMap<String,String> hm = new HashMap<String,String>();
hm.put("John","1");
hm.put("Alex","2");
hm.put("Mike","3");
hm.put("Justin","4");
hm.put("Code","5");

==========================
    Expected Output     
==========================  

Key = John",Value = "1"
Key = Alex",Value = "2"
Key = Mike",Value = "3"
Key = Justin",Value = "4"
Key = Code",Value = "5"
===========================

I need Java code to prevent Addition of Duplicate <Key,Value> Pairs in HashMap such
that below conditions are staisfied.
1> hm.put("John","1"); is not accepted/added again in the Map
2> hm.put("John","2"); is not accepted/added again in the Map

Hope its clear. Java code provided will be appreciated.(generic solution needed since i can add any duplicate to the existing map)

Deepak
  • 2,094
  • 8
  • 35
  • 48
  • 2
    What do you actually want to do? Detect this at run-time, fix this (trivial) example in your code, or actually automatically modify the Java source code (hopefully not)? – Matthew Flaschen Dec 11 '10 at 08:01
  • 13
    **You can't have duplicate Key/Value pairs in a HashMap** -- because you can't have duplicate Keys. Perhaps the problem/post can be clarified? –  Dec 11 '10 at 08:02
  • Also, @pst is right. To clarify, there's only one value per key, since new values replace old ones. However, you *can* use put's return value to determine if it's a new key. – Matthew Flaschen Dec 11 '10 at 08:04
  • @pst and @ matthew(fix at run time in the code by writing an algo),this is the question which i have ,suppose i have 100000000 elements i cannot iterate through the entire hm.size();any other way of doing,Please share the java code for the same – Deepak Dec 11 '10 at 08:04
  • Where do you get the values from? (John-1, John-1, Alex-2, ...) – True Soft Dec 11 '10 at 08:30
  • What happens if you have 2 entries with different values? E.g. John-1 and John-2 – True Soft Dec 11 '10 at 08:30
  • @TrueSoft,just any other HashMap. – Deepak Dec 11 '10 at 08:32
  • If you iterate through another HashMap, you will __never__ get the same keys, nor the same key-values. – True Soft Dec 11 '10 at 08:38
  • @All,The question is re phrased.Please check – Deepak Dec 11 '10 at 08:51
  • 1
    What do you mean by `Console Output`? I don't see any `System.out.println`. – True Soft Dec 11 '10 at 09:06
  • 1
    The "Expected Output" remains unclear. Expected from what? Your code fragment produces no output. – Paul A. Hoadley Dec 11 '10 at 11:59
  • 1
    @Deepak - This question has a lot of contributions from the community. Please consider simply revising it to make it more useful. – Tim Post Feb 21 '11 at 10:42
  • @ Tim, im literally taken aback since they downvote my post,If it is contributing to the community then why keep on incrementing the downvoting counter.it does bring down the reputation on Stack overflow.I have worked on most of the threads on Stack overflow.I have also accepted the solution but still the down voting continues.if down voting is there,i recommend you to close this post.Please consider the reputation that gets affected as well. – Deepak Feb 21 '11 at 15:24
  • Thanks all for your help and explanations please close this thread now since i have accepted the solution. – Deepak Feb 21 '11 at 15:27

8 Answers8

9

You can wrap HashMap in a class, which delegates put, get, and other methods you use from HashMap. This method is wasteful but safe, since it doesn't depend on the internal implementation of HashMap, AbstractMap. The code below illustrates put, get delegating:

    public class Table {
       protected java.util.HashMap<String, Integer> map = 
             new java.util.HashMap<String, Integer>();

       public Integer get(String key) { return map.get(key); }

       public Integer put(String key, Integer value) {
          if (map.containsKey(key)) {
           // implement the logic you need here.
           // You might want to return `value` to indicate
           // that no changes applied
           return value;
          } else {
            return map.put(key, value);
          }
       }
       // other methods goes here
    }

Another option is to make a class which extends HashMap, and depend on its internal implementation. Java 1.6 sources shows that put is called only in putAll in HashMap, so you can simply override put method:

    public class Table extends java.util.HashMap<String, Integer> {
       public Integer put(String key, Integer value) {
          if (containsKey(key)) {
           // implement the logic you need here.
           // You might want to return `value` to indicate
           // that no changes applied
           return value;
          } else {
            return super.put(key, value);
          }
       }
    }

Another option is similar to the first, and can make an utility method in your class which contains the HashMap instance and call that method wherever you need put something to your map:

public final Integer putToMap(String key, String value) {
   if(this.map.containsKey(key)) {
      return value;
   } else {
      return this.map.put(key, value);
   }
}

This is an "inline" equivalent of checking manually.

khachik
  • 28,112
  • 9
  • 59
  • 94
  • 2
    Deepak, I think khachik is giving you this one on a plate. What exactly do you want khachik to alter? All you've supplied is a small code fragment that doesn't even demonstrate your requirement, since it doesn't attempt to insert duplicate keys. – Paul A. Hoadley Dec 11 '10 at 12:02
  • 4
    @Deepak please try to do something for yourself. Programming is an activity for people who like to think and solve problems. – Karl Knechtel Dec 11 '10 at 12:28
3

I note that you clarify the question by suggesting you might have "100000000 elements". You still won't have duplicates in the HashMap, because, as two other posters have pointed out, you can't get duplicate keys in a Map. I'm still not sure we understand the question, though, as it's not at all clear how you expected to generate the block titled "Output", or what you intend to do with it.

Paul A. Hoadley
  • 1,518
  • 1
  • 13
  • 17
  • @paul,My question is to prevent addition of duplicate Pairs to the map if one already exists – Deepak Dec 11 '10 at 08:11
  • 1
    You literally can't add "duplicate Pairs" to a Map, so I suspect you actually mean something else. Do you mean that if there's already a key K with a value V1, you want to prevent changing K's value to V2 by calling hm.put(K, V2)? Trying to add a duplicate (hm.put(K, V1)) would leave the Map unchanged. – Paul A. Hoadley Dec 11 '10 at 08:18
  • @Paul,something on those lines as you have said.yes – Deepak Dec 11 '10 at 08:29
  • 1
    @Deepak: You don't prevent it. The container prevents it. It does so automatically. It already comes with code that prevents it. A Map cannot contain duplicate keys. That's part of what it **means** to be a Map. If you try, it will just replace the old value. You could have found this out for yourself by **reading the documentation**. – Karl Knechtel Dec 11 '10 at 08:58
  • @Karl,i do understand your reply,i need that code which the container is doing (or) how does it internally implement it.Hope you get now – Deepak Dec 11 '10 at 09:01
  • Why do you need it? Just use the container. – Karl Knechtel Dec 11 '10 at 09:06
  • Why do you need that code? Why bother doing something that the map will do anyway? Just look in the sourcecode of HashMap - http://www.docjar.com/html/api/java/util/HashMap.java.html#551 – True Soft Dec 11 '10 at 09:09
  • @this was asked in Intw and they told me i need to know how it internnally detects duplicates and eleiminates them – Deepak Dec 11 '10 at 09:11
  • It is done using the `hashcode` ( http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#hashCode%28%29 ) method of each object. – True Soft Dec 11 '10 at 09:18
  • Yes @TrueSoft,do u know how to implement it viz hashCode.could you share the code – Deepak Dec 11 '10 at 09:21
  • @TrueSoft,Unable to figure out,Could you please share it. – Deepak Dec 11 '10 at 09:25
  • khachik has given you the entire answer, if we're interpreting your question correctly. Extend the Map by inheritance or composition and insert any additional code you need exactly where he indicates. – Paul A. Hoadley Dec 11 '10 at 12:04
1

This may be old question but I thought to share my experience with this. As others pointed out you can't have the same element in a HashMap. By default HashMap will not allow this but there are some cases that you could end up with two or more elements are almost alike that you do not accept but HashMap will. For example, the following code defines a HashMap that takes an array of integers as a key then add :

HashMap<int[], Integer> map1 = new HashMap<>();
int[] arr = new int[]{1,2,3};
map1.put(arr, 4);
map1.put(arr, 4);
map1.put(arr, 4);

At this point, the HashMap did not allow dublicating the key and map1.size() will return 1. However, if you added elements without creating the array first things will be different:

HashMap<int[], Integer> map2 = new HashMap<>();
map2.put(new int[]{4,5,6}, 6);
map2.put(new int[]{4,5,6}, 6);
map2.put(new int[]{4,5,6}, 6);

This way, the HashMap will add all the three new elements so the map2.size() will return 3 and not 1 as expected.

The explanation is that with the first map I created the object arr once and tried to add the same object 3 times which HashMap does not allow by default so only the last usage will be considered. With the second map, however, evey time I recreate a new object on the stack. The three objects created are different and separated thought the three of them have the same data but they are different. That's why HashMap allowed them as different keys.

Bottom line, you don't need to prevent HashMap from adding dublicated keys because it won't by design. However, you have to watch out how you define these keys because the fault may be on your side.

Ahmed salah
  • 311
  • 1
  • 11
0
List<String> keys = new ArrayList<String>(); (1000000)
List<String> values = new ArrayList<String>(); (1000000)
Map<String, String> map = new HashMap<String, String>();
int i =0;
for(String key : keys){
  String returnedValue = map.put(key, values.get(i));
  if(returnedValue!=null){
         map.put(key, returnedValue);
         system.out.println("Duplicate key trying to be entered with new value so   reverting the duplicate key ="+key+"new Value"+values.get(i));
  }
}
deepa
  • 9
  • 1
0

Unfortunately, it is the way that Map works. The easiest workaround is to remove all pre existed keys and their values by calling hm.remove() first! like this:

for (String name : names) {
     hm.remove(name);
     hm.put(name,uri.getQueryParameter(name));
}

And if you don't use a for loop just call it like this:

 hm.remove("John");
 hm.put("John","1");
 hm.remove("Alex");
 hm.put("Alex","2");
 hm.remove("Mike");
 hm.put("Mike","3");
 
 And so on ...
 
mahdi azarm
  • 340
  • 2
  • 7
  • 18
-1

see even if u write same key values multiple times you will just have unique set of pairs. Check that by either iterating or by doing hm.size();

sushil bharwani
  • 29,685
  • 30
  • 94
  • 128
-1
if(hm.put("John","1") != null)
{
  // "John" was already a key in the map.  The sole value for this key is now "1".
}
Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
-1
List<Object> yourElements = new ... // 10000000
for(Object O : yourElements) {
 if(myMap.get(O.key)==null) {
    myMap.put(O.key,O);
 }
}
InsertNickHere
  • 3,616
  • 3
  • 26
  • 23
  • Could you explain with my code what you are trying to achieve – Deepak Dec 11 '10 at 08:20
  • @Deepack Since its not so clear what you want, this code just fills a hashmap but takes always the first occourence of an certain key and throws away the others. – InsertNickHere Dec 11 '10 at 08:34
  • Please check @Paul A. Hoadley comment below in the same post,he has explained my problem. – Deepak Dec 11 '10 at 08:37