Java中的Varargs到ArrayList问题

时间:2011-03-18 13:06:42

标签: java generics variadic-functions

我不明白为什么以下不起作用:

public void doSomething(int... args){
  List<Integer> broken = new ArrayList<Integer>(Arrays.asList(args))
}

我的理解是编译器将“int ... args”转换为数组,因此上面的代码应该可以工作。

而不是工作我得到:

  

无法找到符号   symbol:构造函数ArrayList(java.util.List <int[]&gt;)   location:类java.util.ArrayList <java.lang.Integer&gt;

太怪异了。我没有在数组列表中添加数组,我将列表中的每个元素添加到arraylist中。怎么回事?

4 个答案:

答案 0 :(得分:38)

Java无法自动装箱阵列,只能使用单个值。我建议将方法签名更改为

public void doSomething(Integer... args)

然后在调用doSomething时进行自动装箱,而不是在调用Arrays.asList时尝试(并失败)。

现在正在发生的事情是,Java会在传递给您的函数时自动对每个值进行自动装箱。您之前尝试做的是,通过将int[]传递给Arrays.asList(),您要求该功能进行自动装箱。

但是自动装箱是由编译器实现的 - 它看到你需要一个对象但是传递了一个原语,所以它会自动插入必要的代码以将它变成一个合适的对象。 Arrays.asList()函数已经编译并期望对象,编译器无法将int[]转换为Integer[]

通过将自动装箱移动到您的功能的来电者,您已经解决了这个问题。

答案 1 :(得分:14)

你可以做到

public void doSomething(int... args){
    List<Integer> ints = new ArrayList<Integer>(args.length);
    for(int i: args) ints.add(i);
}

public void doSomething(Integer... args){
    List<Integer> ints = Arrays.asList(args);
}

答案 2 :(得分:7)

在这种情况下,自动装箱(从int自动转换为Integer)不起作用。您必须手动将每个int添加到列表中。

如果您经常需要这样的代码,请考虑使用commons lang具有org.apache.commons.lang.ArrayUtils.toObject(int[])

的代码

答案 3 :(得分:3)

您可以使用Guava解决此问题:

List<Integer> broken = new ArrayList<>(Ints.asList(args))

或使用流:

List<Integer> broken = Arrays
    .stream(array)
    .boxed()
    .collect(Collectors.toCollection(ArrayList::new));