Я пытаюсь передать ограниченное количество значений в набор, но мне нужно проверить, что они являются новыми элементами, прежде чем применять ограничение. Например:Могут ли последовательные потоковые операции иметь побочные эффекты?
Set<Integer> destination = ...
Set<Integer> source = ...
source.stream()
.filter(i -> !destination.contains(i))
.limit(10)
.forEach(destination::add);
Но избыточная проверка меня беспокоит, так как add()
может как добавить элемент и отчет, является ли это новой для коллекции. Так что я думал сделать это:
source.stream()
.filter(destination::add)
.limit(10)
.forEach(i -> {}); // no-op terminal operation to force evaluation
Игнорирование Hacky работу терминала, есть проблема с помощью операции фильтра с побочным эффектом, который, как правило, не рекомендуется. Я понимаю, почему было бы небезопасно использовать map()
и filter()
с побочными эффектами на параллельные потоки. Мой вопрос: приемлемо ли это для последовательного потока, как в этом случае? Если нет, почему бы и нет?
Я думаю, вы немного неправильно поняли мой сценарий. 'source' - это набор, поэтому он не содержит повторяющихся элементов. Я пытаюсь убедиться, что мы добавляем элементы 'source', которые не * уже * существуют в' destination'. Поэтому я думаю, что первое решение все равно будет работать. Но ваш общий момент интересен, а именно, что элемент потока может не перемещаться по всему трубопроводу сразу. У вас есть источник для этого, или вы полагаетесь на отсутствие документации в обратном? – shmosel
Отсутствие документации, напротив, * и * тот факт, что множество оптимизаций в потоках включают элементы обработки в кусках. Код, который вы написали, сегодня работает, но он полагается на вещи, которые могут очень хорошо измениться в новых версиях Java или других реализациях. –
Я действительно неправильно понял цель проверки. Я отредактировал ответ соответственно –