2014-02-17 3 views
5

Я просто хочу спросить, возможно ли инициализировать больше объектов с одним и тем же конструктором в одной команде?Инициализация объекта массива Java

Пример кода:

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

Спасибо за ответ.

+4

Нет, это невозможно. Используйте цикл for. –

+0

Спасибо за быстрый ответ. – user2899587

ответ

4

Невозможно, насколько я знаю. Код Tile[] tiles = new Tile[20]; просто создает массив ссылок. Для того, чтобы заполнить массив, вы должны создать Tile объект, а затем присвоить ссылку на один индекс массива, например:

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

Если все элементы массива, указывающий на тот же объект в порядке, вы можете полный заполнить массив просто используйте:

Tile tiles = new Tile[20]; 
Arrays.fill(tiles, new Tile(5,5)); 
+0

Практически самое короткое, что вы можете сделать с JDK libs. –

+0

Arrays.fill - выглядит полезно спасибо :) – user2899587

+3

@ user2899587 Обратите внимание, что 'Arrays.fill' заполняет массив одним объектом. – Radiodef

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

Я думаю, что это своего рода Nifty.

Существует также несколько способов сделать это без 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!"); 

Отражение немного более неустойчивым, чем лямбда, особенно при работе с подтипами и примитивами. Лямбда велика.

+0

yap, очень умный, спасибо за объяснение – user2899587

+0

oops ... думал о точном решении, но я был замешан в публикации: P –

+0

Здесь [на TryJava8.com] (http://www.tryjava8.com/app/фрагменты/5301866be4b0ded740bd129d). – Radiodef

0

Во-первых, это даже невозможно инициализировать массив объектов с ненулевым значением в одной строке (ок, за исключением использования {...} или наполняя их же ссылкой, но я думаю, что это не то, что вы хотите)

Сначала нужно создать экземпляр массива и заполнить отдельный элемент в массиве:

eg

Foo[] myArray =new Foo[10]; 
for (int i = 0; i < myArray.length; ++i) { 
    myArray = new Foo(); 
} 

Если вы просто ищете короткий код, который вы не хотите, чтобы написать цикл снова и снова, вот один вариант для вас:

написать немного Util так:

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, я считаю (есть не пробовал) вы можете использовать выражение лямбда, которое дает вам что-то вроде

Foo[] fooArray = fillArray(new Foo[10], i -> new Foo(10,10)); 
Смежные вопросы