I am trying to generate pairs of integers - I have a class Pair with a constructor taking 2 ints. The following code works but seems rather clunky - in particular the conversion from an intStream to an object stream using mapToObj(Integer::new).
private static List<Pair> success() {
    return IntStream.range(0, 10).
            mapToObj(Integer::new).flatMap(i -> IntStream.range(12, 15).
                mapToObj(j -> new Pair(i, j))).
            collect(Collectors.toList());
}
Firstly does anyone have a more elegant way to do this ?
Secondly when I refactored to extract some streams as variables, I get an error: IllegalStateException: stream has already been operated upon or closed. Here is the refactored method - does anyone know if this a problem with the code ?
static List<Pair> fail() {
    Stream<Integer> outer = IntStream.range(0, 10).mapToObj(Integer::new);
    IntStream inner = IntStream.range(12, 15);
    Stream<Pair> pairStream = outer.flatMap(i -> 
            inner.mapToObj(j -> new Pair(i, j)));
    return pairStream.collect(Collectors.toList());
}
                It is possible to make it a bit more concise by replacing mapToObj(Integer::new) with boxed- but apart from that, Java is not that concise:
IntStream.range(0, 10)
        .boxed()
        .flatMap(i -> IntStream.range(12, 15)
                               .mapToObj(j -> new Pair(i, j)))
        .collect(Collectors.toList());
As for the second question: There are other answers which link to the problem. The concrete problem is that inner is not used once, but each time of the outer flatMap().
This way it works:
        final IntStream range = IntStream.range(0, 10);
        List<Pair> ps =  range
               .boxed().flatMap(i -> {
                   final IntStream range1 = IntStream.range(12, 15);
                   return range1.
                           mapToObj(j -> new Pair<>(i, j));
               }).
            collect(Collectors.toList());
                        Why not use plain for-loops? Plain for-loops will:
static List<Pair> fail() {
    List<Pair> pairs = new ArrayList<>(30);
    for (int i = 0; i < 10; i++) {
        for (int j = 12; j < 15; j++) {
            pairs.add(new Pair(i, j));
        }
    }
    return pairs;
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With