Khemraj Sharma
Khemraj Sharma

Reputation: 58934

How to initialize generic array?

This method is used to split array into chunks reference. I want to make this method generic.

Problem is, I can not initialize array like this.

T[][] arrays = new T[chunks][];

complete method

 public <T> T[][] splitArray(T[] arrayToSplit, int chunkSize) {
        if (chunkSize <= 0) {
            return null;
        }
        int rest = arrayToSplit.length % chunkSize;
        int chunks = arrayToSplit.length / chunkSize + (rest > 0 ? 1 : 0);
        T[][] arrays = new T[chunks][];
        for (int i = 0; i < (rest > 0 ? chunks - 1 : chunks); i++) {
            arrays[i] = Arrays.copyOfRange(arrayToSplit, i * chunkSize, i * chunkSize + chunkSize);
        }
        if (rest > 0) {
            arrays[chunks - 1] = Arrays.copyOfRange(arrayToSplit, (chunks - 1) * chunkSize, (chunks - 1) * chunkSize + rest);
        }
        return arrays;
    }

What is correct way to initialize generic array?

Upvotes: 5

Views: 16125

Answers (3)

Eugene
Eugene

Reputation: 120848

You can't create a generic array, but you can declare a generic array.

T[] test = null; // works
T[] test2 = new T[10]; // fails
T[] test3 = (T[]) new Object[10]; // works

At the same time, you should be careful with this

Upvotes: 3

prunge
prunge

Reputation: 23238

You can't make a generic array directly since type variable information is lost at runtime due to erasure.

However, in your case there is a workaround, since the output type of the method is just an array of type arrayToSplit and arrays in Java do have their type information available at runtime.

So instead of:

T[][] arrays = new T[chunks][];

you can do:

T[][] arrays = (T[][])Array.newInstance(arrayToSplit.getClass(), chunks);

Mixing arrays and generics can be confusing and error-prone though. If possible, I would use the collections API where possible and use List<T> instead of arrays.

Guava even has a method that I think does exactly what you want:

Lists.partition(List, int)

Returns consecutive sublists of a list, each of the same size (the final list may be smaller). For example, partitioning a list containing [a, b, c, d, e] with a partition size of 3 yields [[a, b, c], [d, e]] -- an outer list containing two inner lists of three and two elements, all in the original order.

Upvotes: 1

Sweeper
Sweeper

Reputation: 270758

You cannot initialise arrays with a generic parameter. That is a restriction on generics.

A workaround is to create an Object[][] and cast it to T[][]:

T[][] arrays = (T[][])new Object[chunks][];

Upvotes: 9

Related Questions