I am building an object with a simple loop:
WebTarget target = getClient().target(u);
for (Entry queryParam : queryParams.entrySet()) {
It's not very difficult to implement a correct foldLeft
for Java 8 streams:
@SuppressWarnings("unchecked")
public static U foldLeft(Stream stream,
U identity, BiFunction accumulator) {
Object[] result = new Object[] { identity };
stream.forEachOrdered(t -> result[0] = accumulator.apply((U) result[0], t));
return (U) result[0];
}
Or in type-safe manner:
public static U foldLeft(Stream stream,
U identity, BiFunction accumulator) {
class Box {
U value;
Box(U value) { this.value = value; }
}
Box result = new Box(identity);
stream.forEachOrdered(t -> result.value = accumulator.apply(result.value, t));
return result.value;
}
This works correctly for sequential and parallel streams. You can even have a speed gain using parallel streams if your stream has some CPU-consuming stateless intermediate operations like map
: in this case the next element can be processed by map
in the parallel with the current element processed by foldLeft
. I don't agree that such operation is not suitable for Stream API, because it can be correctly expressed via already existing forEachOrdered
.
I have this operation in my StreamEx library, so you can use it like this:
WebTarget target = EntryStream.of(queryParams).foldLeft(getClient().target(u),
(t, entry) -> t.queryParam(entry.getKey(), entry.getValue()))