Удалить элемент из набора

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

public static void removeEvenLength(Set<String> list) {
    for (String s : list) {
        if (s.length() % 2 == 0) {
            list.remove(s);
        }
    }
}

3 ответа

Решение

Set не имеет понятия индекса элемента. Элементы не имеют порядка в наборе. Кроме того, вы должны использовать Iterator при итерации, чтобы избежать ConcurrentModificationException при удалении элемента из коллекции при зацикливании:

for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
    String s =  iterator.next();
    if (s.length() % 2 == 0) {
        iterator.remove();
    }       
}

Обратите внимание на призыв к Iterator.remove() вместо Set.remove(),

Java 8 представила Collection.removeIf (), которая позволяет вам делать:

set.removeIf(s -> s.length() % 2 == 0)

Просто подумал, что выложу решение Java 8, которое может кому-то помочь в будущем. Java 8 Streams предлагает множество хороших методов, таких как filter а также collect, filter Метод просто отфильтровывает элементы из потока, которые следует перенести на следующий шаг. collect Метод объединяет элементы в Collection какой-то или Map,

// The data to filter
final Set<String> strings = 
        new HashSet<>(Arrays.asList("a", "ab", "abc", "abcd"));

// Now, stream it!
final Set<String> odds =
        strings.stream()
               .filter(s -> s.length() % 2 != 0) // keep the odds
               .collect(Collectors.toSet());     // collect to a new set

Это фактически не изменяет исходную коллекцию, но создает новую Set содержащий String объекты нечетной длины.

Для получения дополнительной информации о потоках Java 8 обратитесь к этому превосходному учебнику от Oracle или замечательных JavaDocs.

Вам не нужен индекс. Но вам нужно явное Iterator, Итератор имеет remove() метод, без параметров, который удаляет текущий элемент из коллекции.

Iterator<String> itr = list.iterator();  // list is a Set<String>!
while (itr.hasNext())
{
    String s = itr.next();
    if (s.length() % 2 == 0) {
        itr.remove();
    }
}
Другие вопросы по тегам