此次转化有什么问题?
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()
进行排序,我只是对这个很好奇。
答案 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)
此异常有两个原因:
Arrays.asList(factors)
返回List<int[]>
,其中factors
是 int数组
您忘记将类型参数添加到:
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函数的一些事情会有所帮助。