Java数组对象初始化

6

我想问一下,在一个命令中是否可以使用同一个构造函数初始化多个对象?

代码示例:

Tile[] tiles = new Tile(5,5)[20];

感谢回复。

4
不,这是不可能的。使用一个 for 循环。 - Sotirios Delimanolis
感谢您的快速回复。 - user2899587
3个回答

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

使用JDK库,这基本上是您可以做的最短的方式。 - Sotirios Delimanolis
3
请注意,Arrays.fill方法会使用一个单独的对象来填充整个数组。 - Radiodef
出于好奇,这会用该对象的深层复制还是浅层复制填充整个数组? - user2573153
3
只是一个浅拷贝。 - Weibo Li

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非常好。


糟糕...我想到了确切的解决方案,但是我发帖太慢了 :P - Adrian Shum
这里是 TryJava8.com 上的内容。 - Radiodef

0

首先,在一行中使用非空值初始化对象数组甚至是不可能的(好吧,除非使用{...}或使用相同引用填充它们,但我认为这不是你想要的)

你必须先创建数组实例,然后填充数组中的每个元素:

例如:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接