Как передать элементы arrayList в вариационную функцию

У меня есть массив, заполненный элементами. Я хотел бы передать элементы этого списка массивов в качестве аргументов в вариационную функцию.

Моя функция

public SequenceEntityModifier(final IEntityModifier... pEntityModifiers)

My ArrayList

ArrayList<IEntityModifier> arr = new ArrayList<IEntityModifier>();
arr.add(new MoveXModifier(1, 50, 120));
arr.add(new MoveXModifier(1, 120, 50));

Я хотел бы передать его функции, как если бы я передавал их по отдельности.

new SequenceEntityModifier( /* elements of arr here */ );

Что-то вроде этого возможно?

Спасибо заранее.

Ответ 1

Просто выполните:

new SequenceEntityModifier(arr.toArray(new IEntityModifier[arr.size()]));

Это копирует ArrayList в данный массив и возвращает его. Все функции vararg также могут принимать массивы для аргумента, поэтому для:

public void doSomething(Object... objs)

Все юридические вызовы:

doSomething(); // Empty array
doSomething(obj1); // One element
doSomething(obj1, obj2); // Two elements
doSomething(new Object[] { obj1, obj2 }); // Two elements, but passed as array

Одно предупреждение:

Варварские вызовы с примитивными массивами не работают так, как вы ожидали. Например:

public static void doSomething(Object... objs) {
    for (Object obj : objs) {
        System.out.println(obj);
    }
}

public static void main(String[] args) {
    int[] intArray = {1, 2, 3};
    doSomething(intArray);
}

Можно ожидать, что это напечатает 1, 2 и 3 в отдельных строках. Вместо этого он печатает что-то вроде [[email protected] (результат по умолчанию toString для int[]). Это связано с тем, что в итоге создается Object[] с одним элементом, который является нашим int[], например:

// Basically what the code above was doing
Object[] objs = new Object[] { intArray };

То же самое относится к double[], char[] и другим примитивным типам массивов. Обратите внимание, что это можно устранить, просто изменив тип intArray на Integer[]. Это может быть непростым, если вы работаете с существующим массивом, так как вы не можете напрямую передать int[] в Integer[] (см. этот вопрос, я особенно любят ArrayUtils.toObject методы из Apache Commons Lang).

Ответ 2

Конструкция IEntityModifier... представляет собой синтаксический сахар для IEntityModifier[]

См. соответствующий раздел JLS (8.4.1 Формальные параметры)

Ответ 3

Я всегда создаю перегрузку, которая принимает Iterable< ? extends IEntityModifier >, и переходите к этой версии с вариационной версией, используя Arrays.asList(), что дешево.