Удалить ключ в хэш-карте, когда хэш-набор значения пуст

У меня есть хэш-карта, которая сопоставляет ключи строк со значениями хэш-наборов, и я хочу удалить ключ из хэш-карты, когда значение хэш-набора хэш-карт пусто. У меня проблемы с подходом к этому. Вот что я пробовал, но я очень застрял:

for(Map.Entry<String, HashSet<Integer>> entr : stringIDMap.entrySet()) 
{  

                String key = entr.getKey();  

                if (stringIDMap.get(key).isEmpty())
                {

                    stringIDMap.remove(key);
                    continue;
                }
     //few print statements...
}

person Sempiternal    schedule 08.04.2013    source источник
comment
Может ли значение в hashmap, т. е. HashSet‹Integer›, быть нулевым для некоторых строк? С какой проблемой вы столкнулись сейчас? Получение NullPointer?   -  person Jaydeep Rajput    schedule 08.04.2013


Ответы (2)


Во избежание ConcurrentModificationException необходимо напрямую использовать интерфейс Iterator :

Iterator<Map.Entry<String, HashSet<Integer>>> it = stringIDMap.entrySet().iterator();
while (it.hasNext()) {
    Map.Entry<String, HashSet<Integer>> e = it.next();
    String key = e.getKey();
    HashSet<Integer> value = e.getValue();
    if (value.isEmpty()) {
        it.remove();
    }
}

Причина, по которой ваш текущий код не работает, заключается в том, что вы пытаетесь удалить элементы с карты во время итерации по ней. Когда вы вызываете stringIDMap.remove(), это делает недействительным итератор, который цикл for-each использует под прикрытием, делая дальнейшую итерацию невозможной.

it.remove() решает эту проблему, поскольку не делает итератор недействительным.

person NPE    schedule 08.04.2013

Начиная с Java 8, есть отличное короткое решение с лямбдой:

stringIDMap.entrySet().removeIf(ent -> ent.getValue().isEmpty());

или вы можете использовать более краткий способ, передав ссылку на метод

stringIDMap.values().removeIf(Set::isEmpty);

person Ludov Dmitrii    schedule 28.01.2019
comment
лучший вариант stringIDMap.values().removeIf(Set::isEmpty); - person Doogle; 18.02.2019
comment
Да, еще короче, спасибо! Добавлю к моему ответу для большей наглядности. - person Ludov Dmitrii; 19.02.2019