итерация и удаление с карты

Я делал:

for (Object key : map.keySet()) if (something) map.remove(key); 

который бросил исключение ConcurrentModificationException, поэтому я изменил его на:

 for (Object key : new ArrayList(map.keySet())) if (something) map.remove(key); 

это и любые другие процедуры, которые изменяют карту, находятся в синхронизированных блоках.

Есть ли лучшее решение?

если никто не придумает лучшего решения, сначала скажем, что не получает галочку;)

12 Solutions collect form web for “итерация и удаление с карты”

Начиная с Java 1.8, вы можете сделать это с помощью lambda-выражений и streamов:

 map.entrySet().removeIf(e->  ); 

Вот пример кода, чтобы использовать iterator в цикле for, чтобы удалить запись.

 Map map = new HashMap() { { put("test", "test123"); put("test2", "test456"); } }; for(Iterator> it = map.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = it.next(); if(entry.getKey().equals("test")) { it.remove(); } } 

Используйте настоящий iterator.

 Iterator it = map.keySet().iterator(); while (it.hasNext()) { it.next(); if (something) it.remove(); } 

На самом деле вам может потребоваться выполнить итерацию над entrySet() вместо keySet() чтобы сделать эту работу.

Есть ли лучшее решение?

Ну, определенно, лучший способ сделать это в одном заявлении , но это зависит от условия, на котором удаляются элементы.

Например: удалить все те элементы, где value является тестом , а затем использовать ниже:

 map.values().removeAll(Collections.singleton("test")); 

UPDATE Это можно сделать в одной строке, используя выражение Lambda в Java 8.

 map.entrySet().removeIf(e->  ); 

Я знаю, что этот вопрос слишком стар, но нет никакого вреда в обновлении лучшего способа делать вещи 🙂

ConcurrentHashMap

Вы можете использовать java.util.concurrent.ConcurrentHashMap .

Он реализует ConcurrentMap (который расширяет интерфейс Map ).

Например :

 Map map = new ConcurrentHashMap(); for (Object key : map.keySet()) { if (something) { map.remove(key); } } 

Такой подход не оставляет ваш код незатронутым. Только тип map отличается.

Java 8 поддерживает более декларативный подход к итерации, поскольку мы указываем желаемый результат, а не как его вычислять. Преимущества нового подхода заключаются в том, что он может быть более читабельным, менее подверженным ошибкам.

 public static void mapRemove() { Map map = new HashMap() { { put(1, "one"); put(2, "two"); put(3, "three"); } }; map.forEach( (key, value) -> { System.out.println( "Key: " + key + "\t" + " Value: " + value ); }); map.keySet().removeIf(e->(e>2)); // < -- remove here System.out.println("After removing element"); map.forEach( (key, value) -> { System.out.println( "Key: " + key + "\t" + " Value: " + value ); }); } 

И результат заключается в следующем:

 Key: 1 Value: one Key: 2 Value: two Key: 3 Value: three After removing element Key: 1 Value: one Key: 2 Value: two 

Вы должны использовать Iterator для безопасного удаления элемента при перемещении карты.

Я согласен с Полом Томблином. Я обычно использую iterator клавиатуры, а затем основываю свое условие на значение для этого ключа:

 Iterator it = map.keySet().iterator(); while(it.hasNext()) { Integer key = it.next(); Object val = map.get(key); if (val.shouldBeRemoved()) { it.remove(); } } 

Возможно, вы можете перебирать карту, ища ключи для удаления и хранения их в отдельной коллекции. Затем удалите коллекцию ключей с карты. Изменение карты в то время как итерация обычно неодобрительно. Эта идея может быть подозрительной, если карта очень велика.

Альтернативный, более подробный способ

 List toRemove = new ArrayList(); for (SomeObject key: map.keySet()) { if (something) { toRemove.add(key); } } for (SomeObject key: toRemove) { map.remove(key); } 

И это тоже должно работать.

 ConcurrentMap running = ... create and populate map Set> set = running.entrySet(); for (Entry entry : set) { if (entry.getKey()>600000) { set.remove(entry); } } 
 Set s=map.entrySet(); Iterator iter = s.iterator(); while (iter.hasNext()) { Map.Entry entry =(Map.Entry)iter.next(); if("value you need to remove".equals(entry.getKey())) { map.remove(); } } 
  • Java: Как установить точность для двойного значения?
  • Android: Dex не может анализировать код байта версии 52
  • Прочитать pdf-файл из папки с данными
  • не может статически ссылаться на нестатические поля
  • Разрешение на запись на SD-карту
  • Как получить String Array из файла arrays.xml
  • Должен ли я инициализировать переменную внутри конструктора или внешнего конструктора
  • Android: как изменить цвет разделителя datepicker?
  • GSON выбрасывает «Ожидаемый BEGIN_OBJECT, но был BEGIN_ARRAY»?
  • Как я могу начать новую активность Android с помощью строки?
  • Картинка для Android на стене Facebook
  • Interesting Posts

    Игнорирование новых полей объектов JSON с использованием Jackson

    Внешний жесткий диск не отображается в компьютере

    Automount SMB с использованием пароля keychain

    Самый простой способ получить щелчок правой кнопкой мыши «Открыть командное окно здесь» с помощью admin priveleges в Windows 7

    Использование MySQL “IF EXISTS”

    FFMPEG для анимации файлов изображений выводит все-черное видео

    Добавлять изображения с помощью сетки

    Ionic 2 – глобальный NavBar для приложения

    Перегрузка операторов в Java

    Пример сокета клиента Python

    Есть ли приложение Windows или простой способ создания сценариев, чтобы убедить окна завершить работу после завершения процесса?

    DataContract Сериализация XML и атрибуты XML

    В чем разница между «Запросить полезную нагрузку» и «Данные формы», как показано на вкладке «Инструменты разработчика Chrome».

    Как изменить имя пользователя в Windows 7?

    Как динамически удалять элементы из списка ListView при нажатии кнопки?

    Давайте будем гением компьютера.