使用流实例化对象数组
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.stream
或 IntStream.of
来获得 IntStream
(请记住,原语不能作为参数)。
对于map
操作,可以使用参考Layer::new
的方法。
这一切都归结为这个新的代码片段
List<Layer> layers = IntStream.of(layer_sizes).boxed().map(Layer::new).collect(Collectors.toList());
我有一个整数数组,我想用它来实例化一个数组或对象列表。就我而言,老式的做法是:
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.stream
或 IntStream.of
来获得 IntStream
(请记住,原语不能作为参数)。
对于map
操作,可以使用参考Layer::new
的方法。
这一切都归结为这个新的代码片段
List<Layer> layers = IntStream.of(layer_sizes).boxed().map(Layer::new).collect(Collectors.toList());