【问题标题】:java create 2D array from Stream<Integer>java 从 Stream<Integer> 创建二维数组
【发布时间】:2018-04-14 20:38:19
【问题描述】:

我有 Stream Stream&lt;Integer&gt; stream // 1,2,3,4,5,6,7,8,9

我需要从这个stream创建int[3][3]

我该怎么做?

我试过了

int[][] ints = stream
            .map(i -> new int[]{i})
            .toArray(int[][]::new);

但我得到:[[1], [2], [3], [4], [5], [6], [7], [8], [9]]

但我需要:[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

编辑:我认为这不是重复的this,因为我需要 int[3][3] 数组而不是 String[][]

我试过这个例子

int[][] array =
            IntStream.range(0, 3)
                .mapToObj(x -> IntStream.range(0, 3).boxed()
                    .toArray(Integer[]::new))
                .toArray(int[][]::new);

我得到错误

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)

编辑:

int[][] array = stream.collect(() -> new int[3][3],
            (a, i) -> a[(i - 1) / 3][(i - 1) % 3] = i, (a, i) -> {
            });

错误

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();

【问题讨论】:

标签: java arrays java-stream


【解决方案1】:

您可以在 Java 9 中尝试此代码(这会在 Java 8 中引发编译错误,所以要小心):

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)));

结果如下:

[1, 2, 3]
[4, 5, 6]
[7, 8, 9]

使用 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)));

这是另一种解决方案,它支持除预定义序列 (1,2,3,4,5,6,7,8,9) 以外的数字,但由于它使用计数器,因此不像解决方案那样干净数组:

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) -> {});

输出:

[4, 2, 3]
[4, 5, 8]
[9, 8, 11]

如果您想要更多基于上述解决方案的通用解决方案,您可以尝试此代码 sn-p,它允许设置可变数量的列:

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)));

上面的 sn-p 打印:

[4, 2, 3, 4, 5]
[8, 9, 8, 11, 12]
[13, 17, 32, 45, 89]
[91, 91, 98, 87, 0]

【讨论】:

  • 线程“主”java.lang.ArrayIndexOutOfBoundsException 中的异常:3
  • @ip696:是的,如果您使用 1、2、3、4、5、6、7、8、9 以外的其他输入,您可以得到。但是上面的 sn-ps 运行良好。
  • 我在制作时添加了原始值
  • @ip696 使用计数器查看更新的解决方案,以替代 1、2、3、4、5、6、7、8、9 以外的其他数字。
  • 但如果我需要 int[N][M] 其中 N = 1000 000 和 M = 1000 000?
猜你喜欢
  • 2011-02-11
  • 2016-12-27
  • 2012-03-10
  • 1970-01-01
  • 2023-01-04
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
相关资源
最近更新 更多