2017-02-17 7 views
1

У меня есть коллекция, где я бы хотел использовать API потока, чтобы уменьшить его до одного значения. Похоже, что collect или reduce будет работать хорошо, за исключением того, что оба из них хотят, чтобы объект combiner объединял параллельные результаты. В моем случае у меня нет операции объединения.Соберите/уменьшите поток, если не существует функции объединения

В потоке не будет много элементов, поэтому я рад, что он запускается серийно. Есть ли способ справиться с этим?

Если мой поток содержит 1,2 и 3, я хочу сделать эквивалент

result = new Foo().foo(1).foo(2).foo(3); 

Кажется, что

result = stream.reduce(new Foo(), 
         (foo, ele) -> foo.foo(ele), 
         null); 

, скорее всего, работать, но в какой-то момент, некоторые изменения (чуть более длинный список, новая версия Java), будет вызван combiner, и это сломается.

Я возвращаю другой тип, поэтому reduce(BiFunction) не будет работать для меня.

+0

Возможный дубликат [java8 стиля потока для извлечения внутренней части карты через список полей? ] (http://stackoverflow.com/questions/42278737/java8-stream-style-for-retrieving-a-inner-part-of-map-through-a-field-list) – shmosel

+0

Если вас беспокоит по прихоти и милости потока API для использования объединителя, почему бы просто не использовать простой цикл? –

+0

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

ответ

1

Я бы просто использовать цикл по элементам коллекции:

Foo result = new Foo(); 
for (int ele : collection) { 
    result = result.foo(ele); 
} 

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

1

Если вы предпочитаете придерживаться потока, вы можете использовать forEachOrdered как это разрешено быть с сохранением состояния:

AtomicReference<Foo> foo = new AtomicReference<>(new Foo()); 
stream.forEachOrdered(ele -> foo.updateAndGet(f -> f.foo(ele)));   
Foo result = foo.get();