user2899587
user2899587

Reputation: 189

Java array object initialization

I just want ask, is it possible to initiliaze more objects with same constructor in one command?

Example of code:

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

Thanks for response.

Upvotes: 6

Views: 12332

Answers (3)

Radiodef
Radiodef

Reputation: 37835

No, you have to use a loop.

Tile[] tiles = new Tile[20];
for(int i = 0; i < tiles.length; i++) {
    tiles[i] = new Tile(5, 5);
}

However, it is nice that in Java 8 we will be able to shorten this using the new Supplier class and a helper method.

static <E> E[] fill(E[] arr, Supplier<? extends E> supp) {
    for(int i = 0; i < arr.length; i++) {
        arr[i] = supp.get();
    }

    return arr;
}

We can then do the following:

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

I think that's sort of nifty.

There's also a couple ways to do this without Java 8 by using reflection. Here's a way you can do it if the class has a copy constructor (a constructor that takes an object of its own class as an argument):

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

So for example:

String[] arr = fill(new String[5], "Hello world!");

Reflection is a bit more unstable than the lambda, especially when dealing with subtypes and primitives. The lambda is great.

Upvotes: 3

Adrian Shum
Adrian Shum

Reputation: 40036

First, it is even not possible to initialize an object array with non-null value in one line (ok, except using {...} or filling them with same reference but I think it is not what you want)

You gotta create instance of array first, and fill individual element in the array:

e.g.

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

If you are just looking for shorter code that you don't want to write the loop again and again, here is one option for you:

write a little util like this:

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

The way to use is something like

Foo[] fooArray = fillArray(new Foo[10], new ArrayElementFactory<Foo>() {
                                        Foo create(int i) { return new Foo(10,10); }};

If you are using Java8, I believe (haven't tried) you can use lambda expression which give you something like

Foo[] fooArray = fillArray(new Foo[10], i -> new Foo(10,10));

Upvotes: 0

Weibo Li
Weibo Li

Reputation: 3605

Impossible as far as I know. The code Tile[] tiles = new Tile[20]; just creates an array of references. To fill the array, you should create a Tile object and then assign the reference to one index of the array, such as:

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

If all elements of the array pointing to the same object is OK, you can full fill the array simply use:

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

Upvotes: 5

Related Questions