4

I want do a Cartesian product on Quarter on a year between the years specified

Year(2105, 2016) should return Quarter(2015, Q1), Quarter(2015, Q2)... Quarter(2016, Q4)

The enum representing Quarter would be

public enum Quarters {
    Q1, Q2, Q3, Q4
}

and the code I'm trying to come up with is stuck as below

IntStream.rangeClosed(this.getYear(), to.getYear())
    .boxed()
    .map(i -> Arrays
        .stream(Quarters.values())
        .map(q -> new Quarter(i, q))
    );

The above code return Stream<Stream<Quarter>> which I would require to be flattened to Stream<Quarter> any help is appreciated.

Roman
  • 4,922
  • 3
  • 22
  • 31
Somasundaram Sekar
  • 5,244
  • 6
  • 43
  • 85
  • 1
    Use `flatMap` ? – Alexis C. Oct 31 '16 at 09:42
  • 1
    Or maybe also [What's the difference between map and flatMap methods in Java 8?](http://stackoverflow.com/questions/26684562/whats-the-difference-between-map-and-flatmap-methods-in-java-8?noredirect=1&lq=1) – Didier L Oct 31 '16 at 09:53

2 Answers2

5

You can use flatMap to flatten your Stream<Stream<Quarter>> to a Stream<Quarter> :

IntStream.rangeClosed(this.getYear(), to.getYear())
    .boxed()
    .map(i -> Arrays
        .stream(Quarters.values())
        .map(q -> new Quarter(i, q))
        .flatMap(Function.identity())
    );

The body of the flatMap would simply be an identity function.

Or, as Alexis suggested, you can directly use flatMap instead of map :

IntStream.rangeClosed(this.getYear(), to.getYear())
    .boxed()
    .flatMap(i -> Arrays
        .stream(Quarters.values())
        .map(q -> new Quarter(i, q))
    );
Roman
  • 4,922
  • 3
  • 22
  • 31
Eran
  • 387,369
  • 54
  • 702
  • 768
  • 6
    Just use `flatMap(...)` instead of `map(...).flatMap(identity())` – Alexis C. Oct 31 '16 at 09:43
  • @AlexisC. Good point, Thanks! – Eran Oct 31 '16 at 09:49
  • Compilation errors when I tried with the first snippet, flatMap works fine, haven't unit tested, but compiles just fine, so hope will work too. – Somasundaram Sekar Oct 31 '16 at 09:50
  • 2
    @SomasundaramSekar My mistake. The first snippet should use `Function.identity ()`, not a method reference. Anyway, the second snippet is better. – Eran Oct 31 '16 at 09:54
  • Actually, the combination of `map` and `flatMap` has a point, if you use it to avoid the boxing overhead, i.e. instead of `.boxed().flatMap(…)` you can use `.mapToObj(…).flatMap(identity())`. It’s a work-around for the absence of `flatMapToObj`… – Holger Nov 01 '16 at 10:25
1

flatMap( i -> i) will essentially concatenate the streams.

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347