如何将ArrayList的元素传递给可变参数函数

22
我有一个填充了元素的ArrayList。 我想将该ArrayList的元素作为参数传递给可变函数。
我的函数
public SequenceEntityModifier(final IEntityModifier... pEntityModifiers)

我的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 */ );

这样的事情可能吗?

提前致谢。

3个回答

25

只需执行:

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

这将ArrayList复制到给定的数组并返回。所有可变参数函数也可以接受数组作为参数,例如:
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);
}

有人可能期望这段代码会按照顺序打印出123,但实际上它会打印出类似于[I@1242719c的结果(这是int[]类型默认的toString方法的返回值)。这是因为最终它创建了一个只有一个元素的Object[]数组,而这个元素就是我们的int[]数组,例如:

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

同样适用于double[]char[]和其他原始数组类型。请注意,通过将intArray的类型更改为Integer[]就可以简单地解决此问题。如果您正在使用现有数组,则可能不太简单,因为您不能直接将int[]强制转换为Integer[](请参见this question,我特别喜欢Apache Commons Lang中的ArrayUtils.toObject方法)。

1
当然是正确的,但每次我写这样的东西时,我都会感到不舒服——这样的语法纠结。 - Steve B.
@SteveB。我同意,重载是比强制这种方法调用然后在幕后进行转换更好的选择。虽然可变参数很好用,但它们与集合不兼容。 - Brian
不仅是混乱; 还有不必要的(指针)复制,对性能有影响。看下面我的答案,有更便宜的方法。 - Judge Mental

3
构造函数 IEntityModifier...IEntityModifier[] 的语法糖。
请参阅适当的JLS章节8.4.1 形式参数)。

3
我通常会创建一个重载方法,接受 Iterable< ? extends IEntityModifier > 参数,并使用 Arrays.asList() 方法将可变参数版本转发到此方法。这种方式成本较低。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接