繁体   English   中英

数组的Arrays.asList()

[英]Arrays.asList() of an array

这次转换有什么问题?

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中找到的解决方案之后做了这个。 getTheNumber(...)的第二行(排序getTheNumber(...)导致以下异常:

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

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

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

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[]没有自动装箱,反正autoboxing只是编译器中的语法糖,所以在这种情况下你需要手动进行数组复制:

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);
}

您正在尝试将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);
}    

这个例外有两个原因:

1

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

2

你忘了将type参数添加到:

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>

使用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;
}

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

我想你已经找到了一个自动装箱不起作用的例子。 因为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);
}

这适用于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 ...... :-)

这是来自Java API“排序

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

它与实现Comparable接口有关

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM