Using range() method of the IntStream we can create a stream of indices that are valid for these lists.
To filter out indices for which values are not equal, we can apply filter() operation.
Accumulating the result in a list comprised of two elements will require a bit more effort. For that we can use collect(supplier,accumulator,combiner):
- supplier - a function that returns a new mutable container. Here we need to provide a list that should hold the results of reduction;
- accumulator - is a function defines the logic on how to add stream elements into the container;
- combiner - a function that defines how to merge the two containers with partial results obtained while executing the stream in parallel.
List<Integer> a = List.of(1, 2, 5);
List<Integer> b = List.of(1, 2, 8);
List<Integer> result = IntStream.range(0, Math.min(a.size(), b.size()))
.filter(i -> a.get(i) != b.get(i)) // filter out non-equal elements
.collect(
() -> Arrays.asList(0, 0), // supplier - provides a container which contain the results of reduction
(list, i) -> { // combiner - difines the logic on the container should be updated
if (a.get(i) > b.get(i)) list.set(0, list.get(0) + 1);
else list.set(1, list.get(1) + 1);
},
(left, right) -> { // accumulator - provides the logic for merging the two containers while executing in parallel
left.set(0, left.get(0) + right.get(0));
left.set(1, left.get(1) + right.get(1));
}
);
System.out.println(result);
Output:
[0, 1]
In case you doubt where it's a correct way to approach this problem with streams, have a look at the API documentation, paragraph Mutable reduction.
And even if after getting familiar with the reference above, you might think that it can be done without collect(). For instance, why don't we simply apply filter().forEach() to make the code leaner? Then have a look at another part of the API documentation, which is dedicated to Side-effects.