How to stop a reduce operation mid way based on some condition?
For example, how can I find an index of maximum value in a list of integers before hitting 0. So in code below, processing list1 should return 4 (5th element), while processing list2 should return 1 (2nd element, because 8 it is the max value in 5, 8, 3 which are the values before 0).
List<Integer> list1 = Arrays.asList(5, 8, 3, 2, 10, 7);
List<Integer> list2 = Arrays.asList(5, 8, 3, 0, 2, 10, 7);
// This will work for list1 but not for list2
IntStream.range(0, list1.size())
.reduce((a, b) -> list1.get(a) < list1.get(b) ? b : a)
.ifPresent(ix -> System.out.println("Index: " + ix));
Reduction is meant to work on an entire set of values without specifying in which order the actual processing is going to happen. In this regard, there is no “stopping at point x” possible as that would imply an order of processing.
So the simple answer is,
reduce
does not support it, thus, if you want to limit the search range, do the limiting first:Note that you can implement a new kind of
Stream
that ends on a certain condition using the lowlevelSpliterator
interface as described in this answer but I don’t think that this effort will pay off.Starting with Java 9, you can use:
takeWhile
depends on the encounter order of the preceding stream. SinceIntStream.range
produces an ordered stream, it is guaranteed that only the elements before the first mismatching element in encounter order will be used by the subsequent reduction.