Java Set Iterator # remove () или Set # clear () впоследствии? - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть например Set<Object> objects или более конкретный objects = new HashSet<>().

Теперь я хочу перебрать множество, вызвать что-то для каждого элемента, а затем удалить элемент из набора.

Iterator<Object> iterator = objects.iterator();

while (iterator.hasNext()) {
    Object object = iterator.next();
    System.out.println(String.valueOf(object));
    iterator.remove();
}

Лучше (быстрее, удобочитаемее, предпочтительнее) потом использовать Set#clear() вместо Iterator#remove() внутри цикла?

for (Object object : objects) {
    System.out.println(String.valueOf(object));
}

objects.clear();

1 Ответ

0 голосов
/ 06 сентября 2018

Лучше (быстрее, удобочитаемее, предпочтительнее) потом использовать Set#clear() вместо Iterator#remove() внутри цикла?

Нет причин думать, что метод clear() будет медленнее, чем удаление всех элементов по отдельности через итератор. Даже если бы это было реализовано наивно, вы бы ожидали по крайней мере сэкономить на накладных расходах при вызове метода. На практике clear() имеет возможность быть намного более эффективным.

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

Обычно лучше всего сосредоточиться сначала на функциональности, а затем на ясности и простоте. Подумайте над такими вопросами, как то, что должно произойти, если вы прервете в середине итерации по набору: правильно ли для некоторых, но не для всех элементов, которые затем были удалены? Или вам нужен оригинальный размер набора для чего-либо? И т. Д. Производите оптимизацию производительности только тогда, когда и где измерения демонстрируют потенциал для улучшения.

Если действительно оба подхода одинаково хороши с точки зрения функциональности, то позвольте мне заметить, что использование clear() обеспечивает еще большее упрощение, чем просто удаление вызова Iterator.remove() из цикла: вы можете переписать цикл как расширенный for цикл или потоковый конвейер.

Вопрос уже демонстрирует расширенную альтернативу for; Вот потоки один:

objects.stream()
       .forEach(o -> System.out.println(String.valuef(o)));
objects.clear();

Оба из них имеют значительные преимущества ясности по сравнению с вашим исходным кодом Iterator.

...