Здесь есть несколько альтернатив, некоторые из которых уже упоминались другими.
Возможно, наиболее лямбда-подобным подходом будет использование собственного метода агрегирования andThen
(определенного в Consumer
):
Stream<X> exes = ....
exes.forEach(action1
.andThen(action2)
.andThen(action3)
.andThen(...)
.andThen(actionN));
Где все action?
объявлены какConsumer<X>
или Consumer<? super X>
.
Не глядя на документы для подтверждения.Я предполагаю, что действия с 1 по N выполняются одно за другим в одном и том же потоке для каждого элемента в потоке.
Другая возможность здесь - использовать peek
, который в основном передает элементы потока в действие, не потребляя их, так как он возвращает поток, который будет содержать те же элементы.
Stream<X> exes = ...
exes.peek(action1)
.peek(action2)
.peek(action3)
.peek(...)
.forEach(actionN);
Не глядя на документы, держу пари, что:
- вам нужно действительно вызвать финальное действие, например
forEach
(или count
, empty
и т. Д.), Чтобы получитьразные взгляды выполнены. - , что единственным ограничением в порядке выполнения является то, что action-i будет идти перед action-j для любого данного элемента в потоке, пока i
Я считаю, что вы можете использовать Consumer.andThen
на основеоднако содержание вашего вопроса peek
кажется вероятным решением, если есть какое-то действие, выполнение которого не является центральным / основным для поставленной задачи, а скорее как желательный побочный эффект.
Возможно, вы хотите передать измененный поток, который бы "шпионил" за объектами, которые обрабатываются позже кодом, на который была передана ссылка на поток.В этом случае peek
является лучшим, если не единственным вариантом.
Конечно, вы также можете сделать комбинацию обоих.