Because filter
does not work that way, it only filters one collection at a time. For your task, you need something like Python's itertools.product
; this can be implemented using flatMap
. In Scala, this looks as short as:
prices.flatMap(p1 =>
prices.flatMap(p2 =>
if (p1 + p2 == 5) List((p1, p2)) else List()))
If you want to do it in (native) Java, something like this comes out:
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<Integer> prices = Arrays.asList(1,2,3,4,5,6,7,8,9);
List<List<Integer>> result = prices.stream().flatMap(p1 ->
prices.stream().flatMap(p2 ->
p1 + p2 == 5 ? Stream.of(Arrays.asList(p1, p2)) : Stream.empty()
)
).collect(Collectors.toList());
System.out.println(result);
}
}
... which prints [[1, 4], [2, 3], [3, 2], [4, 1]]
. But I wouldn't use that in reality ;) At least, a tuple class would be nice to have.
It is worth noting that flatMap
one of the most powerful functions there is; almost all stream transformations (filter, map, cartesian product, flatten) can be implemented using it. And rest (like zip) is almost always a fold/reduce (or, rarely, an unfold).