Java Collections.rotate()与数组不工作 [英] Java Collections.rotate() with an array doesn't work

查看:203
本文介绍了Java Collections.rotate()与数组不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下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>列表< T> Arrays.asList(T ... a) 。请注意,在这种情况下, 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



另请参见




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 Collections.rotate()与数组不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆