我只想问一下,是否可以在一个命令中使用相同的构造函数初始化更多对象?
代码示例:
Tile[] tiles = new Tile(5,5)[20];
感谢您的回复。
答案 0 :(得分:5)
据我所知,不可能。
代码Tile[] tiles = new Tile[20];
只是创建一个引用数组。要填充数组,您应该创建一个Tile
对象,然后将引用分配给数组的一个索引,例如:
tiles[0] = new Tile(5,5);
如果数组的所有元素都指向同一个对象,那么只需使用完全填充数组:
Tile tiles = new Tile[20];
Arrays.fill(tiles, new Tile(5,5));
答案 1 :(得分:3)
不,你必须使用循环。
Tile[] tiles = new Tile[20];
for(int i = 0; i < tiles.length; i++) {
tiles[i] = new Tile(5, 5);
}
然而,很高兴在Java 8中我们可以使用新的Supplier
类和辅助方法来缩短它。
static <E> E[] fill(E[] arr, Supplier<? extends E> supp) {
for(int i = 0; i < arr.length; i++) {
arr[i] = supp.get();
}
return arr;
}
然后我们可以执行以下操作:
Tile[] tiles = fill(new Tile[20], () -> new Tile(5, 5));
我认为这有点漂亮。
通过使用反射,没有Java 8,还有几种方法可以做到这一点。如果类具有复制构造函数(将其自己的类的对象作为参数的构造函数),则可以使用以下方法:
static <E> E[] duplicate(E[] arr, E element) {
@SuppressWarnings("unchecked")
Class<? extends E> cls = (Class<? extends E>)element.getClass();
try {
Constructor<? extends E> ctor = cls.getConstructor(cls);
for(int i = 0; i < arr.length; i++) {
arr[i] = ctor.newInstance(element);
}
} catch(Exception e) {
e.printStackTrace(System.err);
}
return arr;
}
例如:
String[] arr = fill(new String[5], "Hello world!");
反射比lambda更不稳定,特别是在处理子类型和基元时。 lambda很棒。
答案 2 :(得分:0)
首先,甚至不可能在一行中初始化具有非空值的对象数组(好吧,除了使用{...}
或用相同的引用填充它们但是我认为它不是你想要的)< / p>
首先要创建数组实例,并在数组中填充单个元素:
e.g。
Foo[] myArray =new Foo[10];
for (int i = 0; i < myArray.length; ++i) {
myArray = new Foo();
}
如果您只是在寻找不想一次又一次地编写循环的较短代码,这里有一个选项:
写一个像这样的小工具:
public class ArrayUtil {
public static T[] fillArray(T[] array, ArrayElementFactory elementFactory) {
for (int i = 0; i< array.length; ++i) {
array[i] = elementFactory.create(i);
}
return array;
}
}
public interface ArrayElementFactory<T> {
T create(int i);
}
使用方式类似于
Foo[] fooArray = fillArray(new Foo[10], new ArrayElementFactory<Foo>() {
Foo create(int i) { return new Foo(10,10); }};
如果您使用的是Java8,我相信(还没试过)您可以使用lambda表达式,它可以为您提供类似
的内容Foo[] fooArray = fillArray(new Foo[10], i -> new Foo(10,10));