Статьи

Удаление элементов с карты в Java

Очень короткий и простой пост об удалении элементов с Map в Java. Мы сосредоточимся на удалении нескольких элементов и проигнорируем тот факт, что вы можете удалить один элемент с помощью Map.remove .

Map ниже будет использоваться для этого поста:

1
2
3
4
5
6
Map<Integer, String> map = new HashMap<>();
map.put(1, "value 1");
map.put(2, "value 2");
map.put(3, "value 3");
map.put(4, "value 4");
map.put(5, "value 5");

Есть несколько способов удалить элементы. Вы можете вручную пройтись по коду и удалить их:

1
2
3
4
5
6
for(Iterator<Integer> iterator = map.keySet().iterator(); iterator.hasNext(); ) {
  Integer key = iterator.next();
  if(key != 1) {
    iterator.remove();
  }
}

Вот как бы вы сделали это без доступа к Java 8+. Iterator необходим для предотвращения исключения ConcurrentModificationException при удалении элементов с Map .

Если у вас есть доступ к более новым версиям Java (8+), вы можете выбрать один из следующих вариантов:

1
2
3
4
5
6
// remove by value
map.values().removeIf(value -> !value.contains("1"));
// remove by key
map.keySet().removeIf(key -> key != 1);
// remove by entry / combination of key + value
map.entrySet().removeIf(entry -> entry.getKey() != 1);

removeIf — это метод, доступный для Collection s. Да, сама Map не является Collection и не имеет доступа к самой функции removeIf . Но, используя: values , keySet или entrySet , возвращается содержимое Map . Это представление реализует Collection позволяя removeIf .

Содержимое, возвращаемое values , keySet и entrySet , очень важно. Ниже приведен фрагмент JavaDoc для values :

1
2
3
4
5
6
7
8
* Returns a {@link Collection} view of the values contained in this map.
* The collection is backed by the map, so changes to the map are
* reflected in the collection, and vice-versa.
*
* The collection supports element removal, which removes the corresponding
* mapping from the map, via the {@code Iterator.remove},
* {@code Collection.remove}, {@code removeAll},
* {@code retainAll} and {@code clear} operations.

Этот JavaDoc объясняет, что Collection возвращаемая values , поддерживается Map и что изменение либо Collection либо Map изменит другую. Я не думаю, что могу объяснить то, что JavaDoc говорит лучше, чем то, что там уже написано … Поэтому я перестану пытаться решить эту часть сейчас. Я только показал документацию для values , но вы можете доверять мне, когда я говорю, что keySet и entrySet также поддерживаются содержимым Map . Вы можете сами читать документы, если не верите мне.

Это также ссылается на первый пример с использованием более старой версии Java. В документации указано, что Iterator.remove может быть использован. Это то, что используется ранее. Кроме того, реализация removeIf очень похожа на пример Iterator . Поговорив об этом, я мог бы также показать это:

01
02
03
04
05
06
07
08
09
10
11
12
default boolean removeIf(Predicate<? super E> filter) {
  Objects.requireNonNull(filter);
  boolean removed = false;
  final Iterator<E> each = iterator();
  while (each.hasNext()) {
    if (filter.test(each.next())) {
      each.remove();
      removed = true;
    }
  }
  return removed;
}

В этом есть немного больше. Но, в остальном, это почти то же самое.

Так вот и все. Не так много keySet , кроме как сказать вам, что вы должны помнить, что использование: values , keySet или entrySet предоставит доступ к removeIf позволяющему легко удалять записи Map .

Опубликовано на Java Code Geeks с разрешения Дэна Ньютона, партнера нашей программы JCG . Смотрите оригинальную статью здесь: Удаление элементов с карты в Java

Мнения, высказанные участниками Java Code Geeks, являются их собственными.