удалить элемент хеш-таблицы в итерации - PullRequest
2 голосов
/ 04 марта 2011

Является ли следующий код безопасным способом удаления элемента из Hashtable?

   Enumeration keys = siCache.keys();  //siCache is Hashtable

    while(keys.hasMoreElements())
    {
        String k = (String) keys.nextElement();
        Object v = siCache.get(k);

       if(condition) siCache.remove(k);

    }

Ответы [ 4 ]

5 голосов
/ 04 марта 2011

Используйте итератор набора записей, набора ключей или набора значений и вызовите Iterator.remove().

3 голосов
/ 04 марта 2011

Удаление элемента из Hashtable при перечислении ключей потенциально опасно. Вот что говорит Javadoc:

"Таким образом, перед одновременной модификацией итератор быстро и чисто дает сбой, вместо того, чтобы рисковать произвольным недетерминированным поведением в неопределенное время в будущем. Перечисления, возвращаемые методами ключей и элементов Hashtable: не быстрое. "

Смысл ясен: произвольное недетерминированное поведение возможно, если вы сделаете это.

Решения:

  • Если вы используете J2SE, используйте keySet(). Или, что еще лучше, не используйте Hashtable.
  • Если вы используете J2ME, создайте список ключей, которые нужно удалить, и удалите их позже ... или усердно молитесь: -).
1 голос
/ 04 марта 2011

Существует четкая разница между использованием ...

Enumeration keys = siCache.keys();

и использованием ...

Iterator iterator = siCache.entrySet().iterator()

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

Что касается того, почему ... Я считаю, что при создании ключей Enumeration в вашем примере это буквальная копия набора ключей таблиц, которая не синхронизируется с изменениями самой таблицы.

Это может или не может быть проблемой для вас.Если таблица используется одновременно, возможно, вы захотите перейти на использование итераторов коллекций.

0 голосов
/ 04 марта 2011

Это безопасно. Но что заставило вас думать, что это не так?

протестировано со следующим кодом.

public static void main(String[] args) {
        // TODO Auto-generated method stub

        Hashtable siCache = new Hashtable();
        siCache.put("key", "value");
        siCache.put("key1", "value1");
        Enumeration keys = siCache.keys();  //siCache is Hashtable

        while(keys.hasMoreElements())
        {
            String k = (String) keys.nextElement();
            Object v = siCache.get(k);

           if(true) siCache.remove(k);

        }
        System.out.println(siCache.size());
    }

выход: 0

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...