Reputation: 3598
I have a collection where I would like to use the stream API to reduce it to a single value. It looks like collect
or reduce
would work well, except that both of them want a combiner
object to merge parallel results. In my case, I do not have a combining operation.
There will not be a lot of elements in the stream, so I am happy to have it run serially. Is there a way to handle this?
If my stream contains 1,2 and 3, I want to do the equivalent of
result = new Foo().foo(1).foo(2).foo(3);
It seems that
result = stream.reduce(new Foo(),
(foo, ele) -> foo.foo(ele),
null);
would likely work, but at some point, some change (slightly longer list, new Java version) the combiner
will get called and that will break.
I am returning a different type, so reduce(BiFunction)
will not work for me.
Upvotes: 4
Views: 906
Reputation: 2789
If you prefer to stick to a stream, you could use forEachOrdered
as it is allowed to be stateful:
AtomicReference<Foo> foo = new AtomicReference<>(new Foo());
stream.forEachOrdered(ele -> foo.updateAndGet(f -> f.foo(ele)));
Foo result = foo.get();
Upvotes: 1
Reputation: 140328
I would just use a loop over the elements of the collection:
Foo result = new Foo();
for (int ele : collection) {
result = result.foo(ele);
}
This is easy to read, of similar verbosity to the streams approach, and you don't have to worry about its behaviour changing unexpectedly because of dark voodoo in the Streams library.
Upvotes: 2