I have a map with duplicate values:
(\"A\", \"1\");
(\"B\", \"2\");
(\"C\", \"2\");
(\"D\", \"3\");
(\"E\", \"3\");
I would like to the map
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();
}
}
If this is yours frequent requirement then DualHashBidiMap
calss of apache's commons.collections will help you more instead of using HashMap
.
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
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.
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);
}
}
If you are looking just to remove the concurrentModification exception, then just replace your HashMap with ConcurrentHashMap.
To know more about ConcurrentHashMap look here