Remove duplicate values from HashMap in Java

心不动则不痛 提交于 2019-12-18 03:39:31

问题


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);
}

回答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




回答2:


    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();
        }
    }



回答3:


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.




回答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?




回答5:


If this is yours frequent requirement then DualHashBidiMap calss of apache's commons.collections will help you more instead of using HashMap.




回答6:


public static void main(String[] args) {
    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.println("Initial Map : " + map);
    for (String s : new ConcurrentHashMap<>(map).keySet()) {
        String value = map.get(s);
        for (Map.Entry<String, String> ss : new ConcurrentHashMap<>(map)
                .entrySet()) {
            if (s != ss.getKey() && value == ss.getValue()) {
                map.remove(ss.getKey());
            }
        }
    }
    System.out.println("Final Map : " + map);
}



回答7:


This can be easily done by putting your hashmap into arraylist. This arraylist is of hashmap type.

ArrayList<HashMap<String, String>> mArrayList=new ArrayList<>();
HashMap<String, String> map=new HashMap<>();
map.put("1", "1");
        mArrayList.add(map);
        map=new HashMap<>();
        map.put("1", "1"); 
        mArrayList.add(map);
        map=new HashMap<>();
        map.put("1", "2");
        mArrayList.add(map);
        map=new HashMap<>();
        map.put("1", "3");
        mArrayList.add(map);
        map=new HashMap<>();
        map.put("1", "2");
        mArrayList.add(map);

for(int i=0;i<mArrayList.size();i++)
        {
            temp=mArrayList.get(i).get("1");
            for(int k=i+1;k<mArrayList.size();k++)
            {
                if(temp.equals(mArrayList.get(k).get("1")))
                {
                    mArrayList.remove(k); 
                } 
            }

        }

Now print your arraylist...all the duplicate values from the hashmap easily removed...This is the easiest way to remove duplicacy




回答8:


This will be helpful to remove duplicate values from map.

    Map<String, String> myMap = new TreeMap<String, String>();
    myMap.put("1", "One");
    myMap.put("2", "Two");
    myMap.put("3", "One");
    myMap.put("4", "Three");
    myMap.put("5", "Two");
    myMap.put("6", "Three");

    Set<String> mySet = new HashSet<String>();

    for (Iterator itr = myMap.entrySet().iterator(); itr.hasNext();)
    {
        Map.Entry<String, String> entrySet = (Map.Entry) itr.next();

        String value = entrySet.getValue();

        if (!mySet.add(value))
        {
            itr.remove();               
        }
    }

System.out.println("mymap :" + mymap);

Output:

mymap :{1=One, 2=Two, 4=Three}




回答9:


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);

   }
}



回答10:


If you are looking just to remove the concurrentModification exception, then just replace your HashMap with ConcurrentHashMap.

To know more about ConcurrentHashMap look here



来源:https://stackoverflow.com/questions/17812454/remove-duplicate-values-from-hashmap-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!