Czy skutecznie usunąć wiele kluczy z mapy?

124

Mam Map<String,String>dużą liczbę par klucz-wartość. Teraz chcę usunąć z tego wybrane klucze Map. Poniższy kod pokazuje, co zrobiłem, aby to osiągnąć.

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

Następnie :

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

To działa. Chcę tylko wiedzieć, jaki byłby lepszy sposób na spełnienie moich wymagań?

Ruchira Gayan Ranaweera
źródło

Odpowiedzi:

241

Zakładając, że zestaw zawiera ciągi, które chcesz usunąć, można skorzystać z keySetmetody a map.keySet().removeAll(keySet);.

keySetzwraca widok zestawu kluczy zawartych w tej mapie. Zestaw jest obsługiwany przez mapę, więc zmiany w mapie są odzwierciedlane w zestawie i odwrotnie.

Wymyślony przykład:

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"
asylias
źródło
twoja sugestia jest świetna. Chyba removeAll (keySet) robi to, co ja tam zrobiłem
Ruchira Gayan Ranaweera
11
pod względem "wydajności" to prawdopodobnie tylko pętla for pod spodem, ale jeśli chodzi o czystszy kod, niezłe zwycięstwo :)
rogerdpack
3

Tylko ze względu na kompletność:

Jak się domyślam, java.util.AbstractSet#removeAlldokonuje iteracji po wszystkich wpisach, ale z jedną małą sztuczką: używa iteratora mniejszej kolekcji:

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());
    }
}
Sebastian
źródło
1

Korzystanie ze strumienia Java:

keySet.forEach(map::remove);
Abdull
źródło