Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a 2D int array using Java 8 stream?

I am trying to generate a int[][] using Java 8 streams.

This is what I have done so far:

objects.parallelStream()
            .map(o -> o.getPropertyOnes()
                    .parallelStream()
                    .map(t-> t.getIndex())  //<-- getIndex() returns int
                    .mapToInt(i -> i)
                    .toArray())            //<-- here I have a Stream<int[]>
            .toArray();                   //lost here

At the end of outer.map() I have a Stream<int[]>, but not sure how to convert that to int[][]. Please suggest.

like image 241
Sayan Pal Avatar asked Dec 19 '22 11:12

Sayan Pal


2 Answers

First you can simplify the map().mapToInt() to mapToInt(t-> t.getIndex()) (maybe you should use a method reference like <type>::getIndex).

As you said you have Stream<int[]> after the map stage. Then you only need to provide an array generator function like:

int[][] array = Stream.of(1, 2, 3, 4)
                      .map(i -> IntStream.range(0, i).toArray())
                      .toArray(int[][]::new);

Output:

[[0], [0, 1], [0, 1, 2], [0, 1, 2, 3]]
like image 193
Flown Avatar answered Dec 29 '22 22:12

Flown


You need a toArray(generator) method that helps us to specify a return type by an IntFunction<T[]> function:

int[][] a = Stream.of(new int[]{1, 2, 3}, new int[]{4, 5, 6}).toArray(int[][]::new);

instead of toArray(), which returns Object[] regardless of an incoming type in a Stream (invokes toArray(Object[]::new) internally):

Object[] a = Stream.of(new int[]{1, 2, 3}, new int[]{4, 5, 6}).toArray();

If you are interested in, behind the scenes, all of this have the following look:

  1. forming a Node [an ArrayNode in our case] (an immutable container for keeping an ordered sequence of elements) from a Pipeline of the previous stage;
  2. array size calculation by using the node size (node.count());
  3. getting a new empty array with a needed length by our IntFunction<T[]> generator (i -> new int[i][] or simply int[][]::new);
  4. copying from the node to this array and returning the latter.
like image 32
Andrew Tobilko Avatar answered Dec 29 '22 22:12

Andrew Tobilko