Remove duplicate values from HashMap in Java
Solution 1
make a reverse HashMap!
HashMap<String, String> map = new HashMap<String, String>();
Set<String> keys = map.keySet(); // The set of keys in the map.
Iterator<String> keyIter = keys.iterator();
while (keyIter.hasNext()) {
String key = keyIter.next();
String value = map.get(key);
map.put(value, key);
}
now that you have the hashMap you need reverse it or print it.
in anyway do not delete while iterating hashMap. save the values in a list and delete them in an outer loop
Solution 2
Assuming that you use Java 8, it could be done using the Stream API
with a Set<String>
that will store the existing values:
Map<String, String> map = new HashMap<>();
map.put("A", "1");
...
System.out.printf("Before: %s%n", map);
// Set in which we keep the existing values
Set<String> existing = new HashSet<>();
map = map.entrySet()
.stream()
.filter(entry -> existing.add(entry.getValue()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.printf("After: %s%n", map);
Output:
Before: {A=1, B=2, C=2, D=3, E=3}
After: {A=1, B=2, D=3}
NB: Strictly speaking a predicate of a filter is not supposed to be stateful, it should be stateless as mentioned into the javadoc in order to ensure that the result remain deterministic and correct even if we use a parallel stream. However here, I assume that you don't intend to use a parallel stream such that this approach remains valid.
Solution 3
Map<String,Object> mapValues = new HashMap<String,Object>(5);
mapValues.put("1", "TJ");
mapValues.put("2", "Arun");
mapValues.put("3", "TJ");
mapValues.put("4", "Venkat");
mapValues.put("5", "Arun");
Collection<Object> list = mapValues.values();
for(Iterator<Object> itr = list.iterator(); itr.hasNext();)
{
if(Collections.frequency(list, itr.next())>1)
{
itr.remove();
}
}
Solution 4
ConcurrentModificationException
happening,because you are removing from map
if (value.equals(nextValue)) {
map.remove(key);
}
You have to remove from iterator
if (value.equals(nextValue)) {
keyIter.remove(key);
}
Coming to the duplicate entry issue,Its pretty simple :Find duplicate values in Java Map?
Solution 5
This can be done using Java 8. The concept of stream is required. The pseudocode, is stream().filter().collect(). If the Initial Map : {A=1, B=2, C=2, D=3, E=3}. Then the required answer after removing the duplicates is {A=1, B=2, D=3} .
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class RemoveDuplicates1 {
public static void main(String[] args) {
//Initial Map : {A=1, B=2, C=2, D=3, E=3}
//After => {A=1, B=2, D=3}
Map<String , String > map = new HashMap<>();
map.put("A", "1");
map.put("B", "2");
map.put("C", "2");
map.put("D", "3");
map.put("E", "3");
System.out.printf("before : " +map );
System.out.println("\n");
Set<String> set = new HashSet<>();
map = map.entrySet().stream()
.filter(entry -> set.add(entry.getValue()))
.collect(Collectors.toMap(Map.Entry :: getKey , Map.Entry :: getValue));
System.out.printf("after => " + map);
}
}
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Admin
Updated on May 12, 2020Comments
-
Admin about 4 years
I have a map with duplicate values:
("A", "1"); ("B", "2"); ("C", "2"); ("D", "3"); ("E", "3");
I would like to the map to have
("A", "1"); ("B", "2"); ("D", "3");
Do you know how to get rid of the duplicate values?
At present, I get 'java.util.ConcurrentModificationException' error.
Thank you.
public static void main(String[] args) { HashMap<String, String> map = new HashMap<String, String>(); map.put("A", "1"); map.put("B", "2"); map.put("C", "2"); map.put("D", "3"); map.put("E", "3"); Set<String> keys = map.keySet(); // The set of keys in the map. Iterator<String> keyIter = keys.iterator(); while (keyIter.hasNext()) { String key = keyIter.next(); String value = map.get(key); System.out.println(key + "\t" + value); String nextValue = map.get(key); if (value.equals(nextValue)) { map.remove(key); } } System.out.println(map); }
-
Rohit Jain almost 11 yearsWell, if you see his code clearly, this won't really solve his problem.
-
AllTooSir almost 11 yearsThis code is wrong , it won't compile and neither does it solves the problem .
-
Suresh Atta almost 11 yearsiterator ,
Iterator<String> keyIter = keys.iterator();
-
AllTooSir almost 11 yearsAnd what is keyIter.remove(key) ?
-
Vincent van der Weele almost 11 yearsIt will still be random which element will be kept (because the order of a
HashMap
is undefined), but if that's no issue, this works fine. -
Suresh Atta almost 11 years@TheNewIdiot :That avoids the exception
The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method.
-
AllTooSir almost 11 yearsPlease go through the syntax first and then the documentation .
-
Suresh Atta almost 11 yearsPlease feel free to edit, If you found some mistake,Or please convey the exact reason why I it won't compile,It's working fine In my IDE.
-
No Idea For Name almost 11 years@Heuster i agree, but he didn't said it's an issue
-
Graeme Moss about 7 yearsStrictly speaking streams shouldn't really be used with a side-effecting filter.
-
Nicolas Filotto about 7 years@GraemeMoss that's right, I added a comment to avoid misuse/misunderstanding
-
hc_dev over 5 yearsSome explanation or links for further details would be helpful. Especially if asked why some Exception thrown there is need.
-
bot13 about 5 years@NoIdeaForName why there is map.add() and not map.put()
-
No Idea For Name about 5 years@bot13 can't say i remember if there was a reason for this, it was 6 years back. works with
put
as well. -
Saroj Kumar Sahoo over 4 yearsIt is only possible if both key and value are of same type
-
Diggi55 over 3 yearsYou can replace .filter() by .distinct()