数组的Arrays.asList()

时间:2009-08-08 12:30:54

标签: java arrays integer arraylist

此次转化有什么问题?

public int getTheNumber(int[] factors) {
    ArrayList<Integer> f = new ArrayList(Arrays.asList(factors));  
    Collections.sort(f);
    return f.get(0)*f.get(f.size()-1);
}

我在阅读Create ArrayList from array中找到的解决方案后做了这个。 getTheNumber(...)中的第二行(排序)导致以下异常:

  

线程“main”中的异常java.lang.ClassCastException:[我不能转换为java.lang.Comparable]

这里有什么问题?我确实意识到可以使用Arrays.sort()进行排序,我只是对这个很好奇。

9 个答案:

答案 0 :(得分:41)

让我们考虑以下简化示例:

public class Example {
    public static void main(String[] args) {
        int[] factors = {1, 2, 3};
        ArrayList<Integer> f = new ArrayList(Arrays.asList(factors));
        System.out.println(f);
    }
}

在println行显示类似“[[I @ 190d11]”的内容,这意味着您实际构建了一个包含int 数组的ArrayList。

您的IDE和编译器应警告该代码中未经检查的分配。您应始终使用new ArrayList<Integer>()new ArrayList<>()代替new ArrayList()。如果您使用过它,那么由于尝试将List<int[]>传递给构造函数,会出现编译错误。

int[]Integer[]没有自动装箱,无论如何,自动装箱只是编译器中的语法糖,所以在这种情况下你需要手动进行阵列复制:

public static int getTheNumber(int[] factors) {
    List<Integer> f = new ArrayList<Integer>();
    for (int factor : factors) {
        f.add(factor); // after autoboxing the same as: f.add(Integer.valueOf(factor));
    }
    Collections.sort(f);
    return f.get(0) * f.get(f.size() - 1);
}

答案 1 :(得分:9)

您正在尝试将int []强制转换为Integer [],这是不可能的。

在从数组中获取List之前,您可以使用commons-lang的ArrayUtils将整数转换为整数:

public int getTheNumber(int[] factors) {
    Integer[] integers = ArrayUtils.toObject(factors);
    ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(integers));
    Collections.sort(f);
    return f.get(0)*f.get(f.size()-1);
}    

答案 2 :(得分:8)

此异常有两个原因:

1

Arrays.asList(factors)返回List<int[]>,其中factors int数组

2

您忘记将类型参数添加到:

ArrayList<Integer> f = new ArrayList(Arrays.asList(factors));

使用:

ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(factors));  

导致编译时错误:

found   : java.util.List<int[]>
required: java.util.List<java.lang.Integer>

答案 3 :(得分:6)

使用java.utils.Arrays:

public int getTheNumber(int[] factors) {
    int[] f = (int[])factors.clone();
    Arrays.sort(f);
    return f[0]*f[(f.length-1];
}

或者如果你想要高效避免所有的对象分配只是实际上做的工作:

public static int getTheNumber(int[] array) {
    if (array.length == 0)
        throw new IllegalArgumentException();
    int min = array[0];
    int max = array[0];
    for (int i = 1; i< array.length;++i) {
        int v = array[i];
        if (v < min) {
            min = v;
        } else if (v > max) {
            max = v;
        }
    }
    return min * max;
}

答案 4 :(得分:2)

Arrays.asList(factors)会返回List<int[]>,而非List<Integer>。由于您正在执行new ArrayList而不是new ArrayList<Integer>,因此您不会遇到编译错误,而是创建包含ArrayList<Object>的{​​{1}},然后您隐式转换arraylist到int[]。当然,当您第一次尝试使用其中一个“整数”时,您会遇到异常。

答案 5 :(得分:2)

我认为你已经找到了一个自动装箱不起作用的例子。因为Arrays.asList(T... a)有一个varargs参数,编译器显然会考虑int []并返回一个List<int[]>,其中包含一个元素。

您应该将方法更改为:

public int getTheNumber(Integer[] factors) {
    ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(factors));  
    Collections.sort(f);
    return f.get(0) * f.get(f.size() - 1);
}

并可能添加此项以实现兼容性

public int getTheNumber(int[] factors) {
    Integer[] factorsInteger = new Integer[factors.length];
    for(int ii=0; ii<factors.length; ++ii) {
        factorsInteger[ii] = factors[ii];
    }

    return getTheNumber(factorsInteger);
}

答案 6 :(得分:1)

这适用于Java 5到7:

public int getTheNumber(Integer... factors) {
    ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(factors));
    Collections.sort(f);
    return f.get(0)*f.get(f.size()-1);
}

在Java 4中没有vararg ......: - )

答案 7 :(得分:0)

这是来自Java API “排序

public static void sort(列表列表) 根据元素的自然顺序,将指定列表按升序排序。列表中的所有元素都必须实现Comparable接口。此外,列表中的所有元素必须是可相互比较的(即,e1.compareTo(e2)不得为列表中的任何元素e1和e2抛出ClassCastException。“

它与实现Comparable接口

有关

答案 8 :(得分:0)

据我了解,集合类中的sort函数只能用于对实现类似接口的集合进行排序。

您正在为它提供一个整数数组。 你应该把它包装在一个已知的Wrapper类中,比如Integer。 整数实现可比较。

自从我研究过一些严肃的Java以来​​,已经有很长一段时间了,但是阅读有关sort函数的一些事情会有所帮助。