Java中的Varargs到ArrayList问题

Ben*_* B. 37 java generics variadic-functions

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

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

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

而不是工作,我得到:

找不到符号符号:构造函数ArrayList(java.util.List <int[]>)location:class java.util.ArrayList <java.lang.Integer>

多奇怪.我没有在数组列表中添加数组,我将列表中的每个元素添加到arraylist中.这是怎么回事?

Jon*_*han 45

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

public void doSomething(Integer... args)
Run Code Online (Sandbox Code Playgroud)

然后在呼叫时进行自动装箱doSomething,而不是在呼叫时尝试(和失败)Arrays.asList.

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

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

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


Pet*_*rey 18

你可以做

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

要么

public void doSomething(Integer... args){
    List<Integer> ints = Arrays.asList(args);
}
Run Code Online (Sandbox Code Playgroud)


Zhe*_*lov 9

您可以使用番石榴解决这个问题:

List<Integer> broken = new ArrayList<>(Ints.asList(args))
Run Code Online (Sandbox Code Playgroud)

或者使用流:

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


Aar*_*lla 7

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

如果你需要这样的代码的时候,可以考虑使用一般语言具有org.apache.commons.lang.ArrayUtils.toObject(int[])