web-dev-qa-db-fra.com

Supprimer les valeurs en double de HashMap en Java

J'ai une carte avec des valeurs en double:

("A", "1");
("B", "2");
("C", "2");
("D", "3");
("E", "3");

Je voudrais avoir la carte

("A", "1");
("B", "2");
("D", "3");

Savez-vous comment vous débarrasser des valeurs en double?

À l'heure actuelle, j'obtiens l'erreur 'Java.util.ConcurrentModificationException'.

Je vous remercie.

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

faire un HashMap inversé!

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

maintenant que vous avez le hashMap, vous devez l'inverser ou l'imprimer.

de toute façon ne pas supprimer en itérant hashMap. enregistrer les valeurs dans une liste et les supprimer dans une boucle externe

7
No Idea For Name
    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();
        }
    }
4
Thananjayan N

ConcurrentModificationException qui se passe, parce que vous supprimez de map

  if (value.equals(nextValue)) {
            map.remove(key);
        }

Vous devez supprimer de iterator

if (value.equals(nextValue)) {
            keyIter.remove(key);
        }

En ce qui concerne le problème des entrées en double, il est assez simple: Trouver des valeurs en double dans Java Map?

2
Suresh Atta

En supposant que vous utilisiez Java 8 , vous pouvez utiliser le Stream API avec un Set<String> qui stockera les valeurs existantes:

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

Sortie:

Before: {A=1, B=2, C=2, D=3, E=3}
After: {A=1, B=2, D=3}

NB: À proprement parler, un prédicat d'un filtre n'est pas censé être stateful , il devrait être apatride comme indiqué dans le javadoc afin de assurez-vous que le résultat reste déterministe et correct même si nous utilisons un flux parallèle. Cependant, ici, je suppose que vous n’avez pas l’intention d’utiliser un flux parallèle de sorte que cette approche reste valable.

2
Nicolas Filotto

Si ceci est votre exigence fréquente, alors DualHashBidiMap les statistiques de commons.collections d'Apache vous aideront davantage au lieu d'utiliser HashMap.

1
Prabhaker

Si vous cherchez uniquement à supprimer l'exception concurrentModification, remplacez simplement votre HashMap par ConcurrentHashMap.

Pour en savoir plus sur ConcurrentHashMap, regardez ici

0
Einstein_AB

Cela sera utile pour supprimer les valeurs en double de la carte.

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

Sortie:

mymap: {1 = un, 2 = deux, 4 = trois}

0
Santhanam

Cela peut être facilement fait en plaçant votre hashmap dans un arraylist. Cet arraylist est du type hashmap.

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

        }

Imprimez maintenant votre liste d'archives ... toutes les valeurs en double de la table de hachage sont facilement supprimées ... C'est le moyen le plus simple de supprimer les doublons.

0
Kimmi Dhingra
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);
}
0
dsahoo188

Cela peut être fait avec Java 8. Le concept de flux est requis. Le pseudocode, Est stream (). Filter (). Collect (). Si la carte initiale: {A = 1, B = 2, C = 2, D = 3, E = 3}. Ensuite, la réponse requise après la suppression des doublons est {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);

   }
}
0
Soudipta Dutta