数组的Arrays.asList()
这个转换有什么问题?
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); }
我读完了从数组创buildArrayList中find的解决scheme后,我做了这个。 getTheNumber(...)
的第二行(sortinggetTheNumber(...)
导致以下exception:
线程“main”中的exceptionjava.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[]
自动装箱,自动装箱只是编译器中的语法糖,所以在这种情况下,你需要手动进行数组拷贝:
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 [],这是不可能的。
您可以使用commons-lang的ArrayUtils将int整数转换为整数,然后从数组中获取列表:
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
你忘了将types参数添加到:
ArrayList<Integer> f = new ArrayList(Arrays.asList(factors));
有:
ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(factors));
导致编译时错误:
发现: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; }
我认为你已经find了一个例子,其中自动装箱并不真正的工作。 因为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); }
Arrays.asList(factors)
返回一个List<int[]>
,而不是一个List<Integer>
。 由于你正在做new ArrayList
而不是new ArrayList<Integer>
你不会得到一个编译错误,但创build一个包含一个int[]
的ArrayList<Object>
,然后隐式地将该ArrayList<Integer>
为ArrayList<Integer>
。 当然,你第一次尝试使用这些“整数”之一,你会得到一个例外。
这从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中没有可变参数… 🙂
这是从Java API“sorting”
public static void sort(List list)根据元素的自然顺序将指定列表按升序sorting。 列表中的所有元素必须实现Comparable接口。 此外,列表中的所有元素必须相互可比(即,e1.compareTo(e2)不得为列表中的任何元素e1和e2抛出ClassCastException)。
它与实现Comparable接口有关
就我所知,集合类中的sorting函数只能用来对实现可比接口的集合进行sorting。
你正在提供一个整数数组。 你可能应该围绕一个已知的Wrapper类(如Integer)进行封装。 整数实现可比较。
我从事过一些严肃的Java的工作已经很长时间了,但是在sorting函数中读取一些内容会有所帮助。