【问题标题】:ArrayStoreException when concatenating two arrays Stream连接两个数组 Stream 时出现 ArrayStoreException
【发布时间】:2019-07-19 17:36:18
【问题描述】:

我正在关注这个Question 并试图获得一种连接两个数组的新方法。

int[] c = {1, 34};
int[] d = {3, 1, 5};

我想出了这个:

 Integer [] res= Stream.of(c, d)
                .flatMap(Stream::of)
                .toArray(Integer[]::new);

上面的编译很好,但我得到了这个异常:

Exception in thread "main" java.lang.ArrayStoreException
    at java.lang.System.arraycopy(Native Method)
    at java.util.stream.SpinedBuffer.copyInto(SpinedBuffer.java:194)
    at java.util.stream.Nodes$SpinedNodeBuilder.copyInto(Nodes.java:1290)
    at java.util.stream.SpinedBuffer.asArray(SpinedBuffer.java:215)
    at java.util.stream.Nodes$SpinedNodeBuilder.asArray(Nodes.java:1296)
    at java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:439)

我的错误是什么,请给出解释,以便我理解这个概念。

PS:我见过Dealing with an ArrayStoreException 并相信我的问题由流组成,这些流是不可比较的类型,这就是它们没有被存储的原因,所以两个问题是不同的。

【问题讨论】:

  • 您的数组是原始数组 (int[]),而您想将它们连接到包装类数组 (Integer[]::new) - 我想说自动装箱在这里不起作用。
  • 我认为您只是误解了解释,因为您刚刚回答了自己的问题。

标签: java java-8


【解决方案1】:

Stream.of 将输入数组视为单个元素。请改用Arrays.stream()

int[] c = {1, 34};
int[] d = {3, 1, 5};

int[] res= Stream.of(c, d)
  .flatMapToInt(Arrays::stream)
  .toArray();

  for (int re : res) {
      System.out.println(re);
  }

结果:

1
34
3
1
5

如果你想把它装箱,去:

Integer[] res= Stream.of(c, d)
  .flatMapToInt(Arrays::stream).boxed()
  .toArray(Integer[]::new);

【讨论】:

  • 当我在 Intellij 编译器中执行 Arrays.stream() 时,编译器提示我 Arrays.stream() 可以写为 Stream.of() ,那么有什么区别?
  • @CommonMan 你在尝试我的例子吗? Stream.of 有两个签名,如果将其放在不同的上下文中,编译器可以推断出错误的签名
  • flatMapToInt(Arrays::stream)有什么意义,会不会只是返回数组流?
  • 如果我用 Stream.of 手动替换它,它不会编译 - 我相信 javac 在这个上
  • 即使它有效,将 array 上的惯用 Arrays.stream 替换为 stream 与恰好接受一个由于数组的方式,varargs 已经在 J​​ava 中实现,是一个非常糟糕的建议。如果你使用IntStream.of,这个技巧会起作用,出于同样的原因Stream.of 适用于对象数组,仍然没有理由替换Arrays.stream
【解决方案2】:

.flatMap(Stream::of) 上的 Stream<int[]> 返回 Stream<int[]>(因为 Stream.of(int[]) 将执行 Stream<T> of(T t) 而不是 Stream<T> of(T... values))。因此这些元素不能存储在Integer[] 数组中。

您可以改用IntStreams:

int [] res= Stream.of(c, d)
                  .flatMapToInt (IntStream::of)
                  .toArray();

【讨论】:

    【解决方案3】:
    Stream.of(c, d)
    

    Stream<int[]>。您不能将 int[] 元素存储在 Integer[] 中。

    改用IntStream.concat

    IntStream.concat(IntStream.of(c), IntStream.of(d)).boxed()
       .toArray(Integer[]::new);
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    • 2016-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多