问题描述
我有以下Java代码:
import java.util.Arrays;
import java.util.Collections;
public class Test {
public static void main(String [] args){
int [] test = {1,2,3,4,5};
Collections.rotate(Arrays.asList(test),-1);
for(int i = 0; i }
}
旋转,但我得到的输出是
1
2
3
4
5
为什么?
这样可以工作:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Test {
public static void main(String [] args){
int [] test = {1,2,3,4,5};
List< Integer> testList = new ArrayList< Integer>();
for(int i = 0; i Collections.rotate(testList,-1);
for(int i = 0; i }
}
但是Arrays.asList返回一个列表,当写入时,将更改复制到数组。有没有办法解决这个问题,而无需手动从数组转换到列表?
我(我认为)不能浪费那么多的CPU时间和内存。
这是一个棘手的问题:是, asList
返回 List
,它返回数组,并且对 List
的更改将数组。但是,由于 T ...
的变量在这种情况下与基本类型数组交互,因此实际上是创建一个包含1个元素的列表。
int [] test = {1,2,3,4,5};
System.out.println(Arrays.asList(test).size());
//打印1
让我们试试不同的东西:
int [] test = {1,2,3,4,5};
List< Integer> list = Arrays.asList(test);
//类型不匹配:不能从List< int []>到List< Integer>
正如你看到的,varargs与 int []
不按照你的意图工作,编译器给出一个错误。 Arrays.asList
实际上会传回一个1元素 List< int []>
c $ c> List< Integer> 。
使用 Integer []
int []
按预期工作:
Integer [] test = 1,2,3,4,5};
Collections.rotate(Arrays.asList(test),-1);
System.out.println(Arrays.toString(test));
//打印[2,3,4,5,1]
更多解释
asList
的完整签名为。请注意,在这种情况下, T
不能是 int
,因为同样的原因, code>在Java中列出< int> : T
需要是引用类型。
考虑下面的代码片段:
System.out.println(Arrays.asList );
//打印[1,2,3]
每个 int
被嵌套到 Integer
中,varargs机制工作和 asList
创建一个包含3个元素的列表。现在考虑下面的形式:
System.out.println(Arrays.asList(new int [] {1,2, 3}));
// prints[[I @ xxxxxx]
c $ c> asList 是一个 int []
。 T
不能是 int
,因此, T ...
varargs机制失败, asList
只有一个元素,它是一个 int []
而不是 int
值本身。
现在考虑这种形式:
System.out.println(Arrays.asList(new Integer [] {1,2,3}));
//打印[1,2,3]
$ c> Integer [] 是一个 T ...
, asList
另请参见
-
-
int []
不会自动移至Integer []
li>
-
I have the following Java code:
import java.util.Arrays;
import java.util.Collections;
public class Test {
public static void main(String[] args) {
int[] test = {1,2,3,4,5};
Collections.rotate(Arrays.asList(test), -1);
for(int i = 0; i < test.length; i++) { System.out.println(test[i]); }
}
}
I want the array to be rotated, but the output I get is
1
2
3
4
5
Why is this?
And is there an alternative solution?
EDIT:
So this works:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Test {
public static void main(String[] args) {
int[] test = {1,2,3,4,5};
List<Integer> testList = new ArrayList<Integer>();
for(int i = 0; i < test.length; i++) { testList.add(test[i]); }
Collections.rotate(testList, -1);
for(int i = 0; i < test.length; i++) { System.out.println(testList.get(i)); }
}
}
But Arrays.asList is supposed to return a list that when written to, copies the changes to the array. Is there any way to fix this without manually doing the conversion from array to list?
I (think that I) can't afford to waste that much CPU time and memory to do the conversion.
This is a tricky problem: yes, asList
backs the List
it returns with the array, and changes to the List
will "write-through" to the array. However, due to how varargs of T...
interacts with an array of primitive type in this case, you're actually creating a list with 1 element!
int[] test = {1,2,3,4,5};
System.out.println(Arrays.asList(test).size());
// prints "1"
Let's try something different:
int[] test = {1,2,3,4,5};
List<Integer> list = Arrays.asList(test);
// "Type mismatch: cannot convert from List<int[]> to List<Integer>"
As you see, the varargs with an int[]
doesn't work the way you intended, and the compiler gives an error. Arrays.asList
actually returns a 1-element List<int[]>
instead of a 5-element List<Integer>
.
Using Integer[]
instead of int[]
works as expected:
Integer[] test = {1,2,3,4,5};
Collections.rotate(Arrays.asList(test), -1);
System.out.println(Arrays.toString(test));
// prints "[2, 3, 4, 5, 1]"
More explanation
The full signature of asList
is <T> List<T> Arrays.asList(T... a)
. Note that T
can't be int
in this case, for the same reason why you can't have a List<int>
in Java: T
needs to be a reference type.
Consider the following snippet:
System.out.println(Arrays.asList(1,2,3));
// prints "[1, 2, 3]"
What happens here is that each int
is boxed into an Integer
, and the varargs mechanism "works" and asList
creates a list of 3 elements. Now consider the following form instead:
System.out.println(Arrays.asList(new int[] { 1,2,3 }));
// prints "[[I@xxxxxx]"
Now the argument to asList
is an int[]
. T
can't be an int
, therefore, the T...
varargs mechanism "fails", and asList
only gets one element, and it's an int[]
, instead of the int
values themselves.
Now consider this form:
System.out.println(Arrays.asList(new Integer[] { 1,2,3 }));
// prints "[1, 2, 3]"
Now since Integer[]
is a T...
, asList
gets 3 elements as expected.
See also
- Java: Array of primitive data types does not autobox
- An
int[]
does not autobox to anInteger[]
- An
这篇关于Java Collections.rotate()与数组不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!