Remove duplicate values from HashMap in Java

96,119

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

   }
}
Share:
96,119
Admin
Author by

Admin

Updated on May 12, 2020

Comments

  • Admin
    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
    Rohit Jain almost 11 years
    Well, if you see his code clearly, this won't really solve his problem.
  • AllTooSir
    AllTooSir almost 11 years
    This code is wrong , it won't compile and neither does it solves the problem .
  • Suresh Atta
    Suresh Atta almost 11 years
    iterator ,Iterator<String> keyIter = keys.iterator();
  • AllTooSir
    AllTooSir almost 11 years
    And what is keyIter.remove(key) ?
  • Vincent van der Weele
    Vincent van der Weele almost 11 years
    It 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
    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
    AllTooSir almost 11 years
    Please go through the syntax first and then the documentation .
  • Suresh Atta
    Suresh Atta almost 11 years
    Please 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
    No Idea For Name almost 11 years
    @Heuster i agree, but he didn't said it's an issue
  • Graeme Moss
    Graeme Moss about 7 years
    Strictly speaking streams shouldn't really be used with a side-effecting filter.
  • Nicolas Filotto
    Nicolas Filotto about 7 years
    @GraemeMoss that's right, I added a comment to avoid misuse/misunderstanding
  • hc_dev
    hc_dev over 5 years
    Some explanation or links for further details would be helpful. Especially if asked why some Exception thrown there is need.
  • bot13
    bot13 about 5 years
    @NoIdeaForName why there is map.add() and not map.put()
  • No Idea For Name
    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
    Saroj Kumar Sahoo over 4 years
    It is only possible if both key and value are of same type
  • Diggi55
    Diggi55 over 3 years
    You can replace .filter() by .distinct()