Эффективно удалить несколько ключей с карты?

124

у меня есть Map<String,String> большое количество пар "ключ-значение". Теперь я хочу удалить из этого выбранные ключи Map. Следующий код показывает, что я сделал для этого.

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

Затем :

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

Это работает. Я просто хочу знать, как лучше всего выполнить мои требования?

Ручира Гаян Ранавира
источник

Ответы:

241

Если предположить , что набор содержит строки , которые вы хотите удалить, вы можете использовать в keySetметод и map.keySet().removeAll(keySet);.

keySetвозвращает представление Set ключей, содержащихся в этой карте. Набор подкреплен картой, поэтому изменения на карте отражаются в наборе, и наоборот.

Надуманный пример:

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"
assylias
источник
ваше предложение отличное. Думаю, removeAll (keySet) делает то же, что и я,
Ручира Гаян Ранауира
11
с точки зрения «эффективности» это, вероятно, просто цикл for внизу, но с точки зрения более чистого кода, хорошая победа :)
rogerdpack
3

Просто для полноты:

Как и предполагалось, на java.util.AbstractSet#removeAllсамом деле выполняется итерация по всем записям, но с одной маленькой хитростью: он использует итератор меньшей коллекции:

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());
    }
}
Себастьян
источник
1

Использование потока Java:

keySet.forEach(map::remove);
Abdull
источник