5

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?

3 Answers 3

9

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][];
Sign up to request clarification or add additional context in comments.

5 Comments

Wrong 1st argument type. Found: 'byte[]', required: 'T[]'
Why does this show error when invoking this method.
Can you please tell syntax to call this method also.
@Khemraj because your method is generic, you can't call it with primitive types: docs.oracle.com/javase/tutorial/java/generics/… Use a Byte[] (note the capital letter).
Thanks @Sweeper because of this answer I check in ArrayList implementation it also more like this. :)
3

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

2 Comments

is there any way to declare a generic array without the java compiler logging "uses unchecked or unsafe operations." when compiling the file that does this? test3 causes that warning
@notacorn no, since you can not declare a generic array, you will always have the cast to T[], always.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.