Collection.toArray(IntFunction<T[]> generator) does not receive the collection size

Viewed 445

Why generateEmptyArrayBySize method is receiving 0 as input, instead of 3? I was expecting to receive the list size.

public class CollectionToArrayTest {
    public static void main(String[] args) {
        var list = List.of(1, 2, 3);
        var array = list.toArray(CollectionToArrayTest::generateArrayBySize);
        out.println("array: " + Arrays.toString(array)); // array: [1, 2, 3]
    }

    private static Integer[] generateArrayBySize(int arraySize) {
        out.println("arraySize: " + arraySize); // arraySize: 0
        return new Integer[arraySize];
    }
}
2 Answers

If you look at the implementation of the Collection.toArray method you'll see:

return toArray(generator.apply(0));

On the other side, the implementation of the IntFunction that you have looks similar to:

new IntFunction<Integer[]>() {
    @Override
    public Integer[] apply(int arraySize) { // check the parameter here
        return generateArrayBySize(arraySize);
    }
}

So the value passed on to the generateArrayBySize is the same as that passed to the apply method of the IntFunction, i.e. 0. Ofcourse, a straight forward way to transform the list into an array would be:

var array = list.toArray(Integer[]::new);

When you call Collection#toArray method, its internal parameter, i.e. array size, is 0 due to the implementation:

default <T> T[] toArray(IntFunction<T[]> generator) {
    return toArray(generator.apply(0));
}

But you can explicitly set it greater than the actual size:

public static void main(String[] args) {
    var list = List.of(1, 2, 3);
    var array = list.toArray(q -> {
        System.out.println("arraySize: " + q); // arraySize: 0
        return generateArrayBySize(4);
    });
    System.out.println(Arrays.toString(array)); // [1, 2, 3, null]
}
private static Integer[] generateArrayBySize(int arraySize) {
    System.out.println("arraySize: " + arraySize); // arraySize: 4
    return new Integer[arraySize];
}

See also: Move null elements for each row in 2d array to the end of that row

Related