Java creates a 2D array from Stream <Integer>
I have a Stream Stream<Integer> stream // 1,2,3,4,5,6,7,8,9
I need to create int[3][3] from this stream
How can i do this?
I tried
int[][] ints = stream .map(i -> new int[]{i}) .toArray(int[][]::new); But I get: [[1], [2], [3], [4], [5], [6], [7], [8], [9]]
But I need: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
EDIT: I think this is not dublicate this , because I need an int [3] [3] array, not a String [] []
I tried this example
int[][] array = IntStream.range(0, 3) .mapToObj(x -> IntStream.range(0, 3).boxed() .toArray(Integer[]::new)) .toArray(int[][]::new); And I get an error
Exception in thread "main" java.lang.ArrayStoreException: [Ljava.lang.Integer; at java.util.stream.Nodes$FixedNodeBuilder.accept(Nodes.java:1222) at java.util.stream.IntPipeline$4$1.accept(IntPipeline.java:250) at java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Streams.java:110) at java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:693) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:545) at java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260) at java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:438) at SparseMatrixSupportImpl.fromStream(SparseMatrixSupportImpl.java:25) at SparseMatrixSupportImpl.fromStream(SparseMatrixSupportImpl.java:4) at Main.main(Main.java:12) EDIT:
int[][] array = stream.collect(() -> new int[3][3], (a, i) -> a[(i - 1) / 3][(i - 1) % 3] = i, (a, i) -> { }); Error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3 at SparseMatrixSupportImpl.lambda$fromStream$1(SparseMatrixSupportImpl.java:28) at java.util.stream.ReduceOps$4ReducingSink.accept(ReduceOps.java:220) at java.util.stream.IntPipeline$4$1.accept(IntPipeline.java:250) at java.util.Spliterators$IntArraySpliterator.forEachRemaining(Spliterators.java:1032) at java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:693) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:510) at SparseMatrixSupportImpl.fromStream(SparseMatrixSupportImpl.java:27) at SparseMatrixSupportImpl.fromStream(SparseMatrixSupportImpl.java:4) at Main.main(Main.java:12) int[] values = new int[]{1, 2, 3,5,6,7,8,9,11}; Stream<Integer> integerStream = Arrays.stream(values).boxed(); You can try this code with Java 9 (this causes a compilation error in Java 8, so be careful):
int[][] array = Stream.iterate(1, i -> i < 10, i -> i + 1).collect(() -> new int[3][3], (a, i) -> a[(i - 1) / 3][(i - 1) % 3] = i, (a, i) -> {}); Stream.of(array).forEach(a -> System.out.println(Arrays.toString(a))); Here is the result:
[1, 2, 3] [4, 5, 6] [7, 8, 9] With Java 8:
int[][] array = IntStream.range(1, 10).collect(() -> new int[3][3], (a, i) -> a[(i - 1) / 3][(i - 1) % 3] = i, (a, i) -> {}); Stream.of(array).forEach(a -> System.out.println(Arrays.toString(a))); Here is another solution that supports numbers other than the predefined sequence (1,2,3,4,5,6,7,8,9), but is not as clean as the solution because it uses an array counter:
int[] counter = {0}; int[][] array = Stream.of(4, 2, 3, 4, 5, 8, 9, 8, 11).collect(() -> new int[3][3], (a, i) -> { a[counter[0] / 3][counter[0] % 3] = i; counter[0]++; }, (a, i) -> {}); Output:
[4, 2, 3] [4, 5, 8] [9, 8, 11] If you want a more universal solution based on the solution above, you can try this piece of code that allows you to set a variable number of columns:
List<Integer> list = Arrays.asList(4, 2, 3, 4, 5, 8, 9, 8, 11, 12, 13, 17, 32, 45, 89, 91, 91, 98, 87); int[] counter = {0}; int cols = 5; int rows = (int) Math.ceil(list.size() / cols) + 1; int[][] array = list.stream().collect(() -> new int[rows][cols], (a, i) -> a[counter[0] / cols][counter[0]++ % cols] = i, (a, i) -> {}); Stream.of(array).forEach(a -> System.out.println(Arrays.toString(a))); The imprint over the inscriptions:
[4, 2, 3, 4, 5] [8, 9, 8, 11, 12] [13, 17, 32, 45, 89] [91, 91, 98, 87, 0]