使用流实例化对象数组

Instantiating array of objects with streams

我有一个整数数组,我想用它来实例化一个数组或对象列表。就我而言,老式的做法是:

int[] layer_sizes = {784, 500, 10};
Layer[] layers = new Layer[layer_sizes.length];
for (int i=0; i<layer_sizes.length; i++)
    layers[i] = new Layer(layer_sizes[i]);

但现在我看到 Java 8 拥有所有这些奇特的流。我现在想做一些类似 Python 的列表理解:

List<Layer> layers = Stream.of(layer_sizes).map(size -> Layer(size));

但它不允许我这样做,我不确定为什么...它给出的信息是

incompatible types: no instance(s) of type variable(s) R exist so that Stream<R> comforms to List<Layer> where R, T are type variables....

有没有一种方法可以使用 Streams 在一行中构造一个对象数组?

编辑:不是与上一个问题的重复,因为事实证明从基元制作流有一些特殊性。

结论

谢谢 Sam Sun 和 Eran。我最终使用的行是这样的:

Layer[] layers = Arrays.stream(layer_sizes).boxed().map(Layer::new).toArray(Layer[]::new);

无论 boxed() 是什么,您都需要它,除非您将 layer_sizes 声明为 Integer 而不是 int.

P.S. 如果 java 开发人员正在阅读这篇文章,那么 Java 9 或接下来的任何东西都会很棒喜欢

Layer[] layers = {new Layer(size) for (size:layer_sizes)}  // OR at least:
Layer[] layers = Stream.of(layer_sizes).map(Layer::new).toArray()

您遗漏了两件事 - 将 Stream 收集到列表中并调用 Layer 构造函数(您遗漏了 new 关键字):

List<Layer> layers = 
    IntStream.of(layer_sizes)
             .mapToObj(size -> new Layer(size))
             .collect(Collectors.toList());

如果您希望输出为数组而不是 List,请调用 toArray 而不是 collect

编辑:

我刚刚意识到 Stream.of 在传递 int[] 时会产生 Stream<int[]>,而不是 Stream<Integer>。因此,您应该使用 IntStream,它处理原始 int 元素。

另一种方法是将输入 int[] layer_sizes = {784, 500, 10}; 替换为 Integer[] layer_sizes = {784, 500, 10};

Eran 的回答大致说明了要做什么,但缺少一些关键细节。

int[] 上使用 Stream.of 将导致 Stream<int[]>; Java.

的神器之一

相反,您应该使用 Arrays.streamIntStream.of 来获得 IntStream(请记住,原语不能作为参数)。

对于map操作,可以使用参考Layer::new的方法。

这一切都归结为这个新的代码片段

List<Layer> layers = IntStream.of(layer_sizes).boxed().map(Layer::new).collect(Collectors.toList());