146 votes

Supprimer plusieurs clés de la carte de manière efficace ?

J'ai un Map<String,String> avec un grand nombre de paires clé-valeur. Maintenant, je veux supprimer les clés sélectionnées de ce Map . Le code suivant montre ce que j'ai fait pour y parvenir.

Set keySet = new HashSet(); //I added keys to keySet which I want to remove. 

Ensuite :

Iterator entriesIterator = keySet.iterator();
while (entriesIterator.hasNext()) {
   map.remove( entriesIterator.next().toString());
} 

Cela fonctionne bien. Quelle serait la meilleure approche ?

290voto

assylias Points 102015

En supposant que votre ensemble contient les chaînes que vous voulez supprimer, vous pouvez utiliser le site keySet méthode y map.keySet().removeAll(keySet); .

keySet renvoie une vue Set des clés contenues dans cette carte. L'ensemble est soutenu par la carte, donc les modifications apportées à la carte sont reflétées dans l'ensemble, et vice-versa.

Exemple artificiel :

Map<String, String> map = new HashMap<>();
map.put("a", "");
map.put("b", "");
map.put("c", "");

Set<String> set = new HashSet<> ();
set.add("a");
set.add("b");

map.keySet().removeAll(set);

System.out.println(map); //only contains "c"

18voto

Maverick283 Points 458

Dans un souci d'achèvement, et puisque Google vous amène ici lorsque vous cherchez un moyen d'y parvenir :

map.entrySet().removeIf(entry -> /* decide what you want to remove here */ );

Cela ne suppose pas que vous ayez un ensemble prédéfini de clés à supprimer, mais plutôt que vous ayez une condition pour laquelle les clés doivent être supprimées. D'après la question, il n'est pas clair si ces clés sont ajoutées manuellement ou en fonction d'une condition quelconque. Dans ce dernier cas, ce code pourrait être le plus propre.

Pour le premier cas, ce code (non testé) pourrait également fonctionner :

map.entrySet().removeIf(entry -> keySet.contains(entry.getKey()) );

Mais évidemment la réponse fournie par @assylias est beaucoup plus propre dans ce cas !

9voto

Sebastian Points 454

Juste pour être complet :

Comme deviné java.util.AbstractSet#removeAll itère réellement sur toutes les entrées, mais avec une petite astuce : il utilise l'itérateur de la plus petite collection :

if (size() <= collection.size()) {
    Iterator<?> it = iterator();
    while (it.hasNext()) {
        if (collection.contains(it.next())) {
            it.remove();
        }
    }
} else {
    Iterator<?> it = collection.iterator();
    while (it.hasNext()) {
        remove(it.next());
    }
}

4voto

Abdull Points 1666

Utilisation du flux Java :

keySet.forEach(map::remove);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X