Remove duplicate values from HashMap in Java

2019-03-20 21:21发布

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

10条回答
甜甜的少女心
2楼-- · 2019-03-20 21:40

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}

查看更多
乱世女痞
3楼-- · 2019-03-20 21:43

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

查看更多
再贱就再见
4楼-- · 2019-03-20 21:52

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.add(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

查看更多
兄弟一词,经得起流年.
5楼-- · 2019-03-20 21:53

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

To know more about ConcurrentHashMap look here

查看更多
做个烂人
6楼-- · 2019-03-20 21:55
    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();
        }
    }
查看更多
相关推荐>>
7楼-- · 2019-03-20 21:55

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.

查看更多
登录 后发表回答