数组的 Arrays.asList()
Posted
技术标签:
【中文标题】数组的 Arrays.asList()【英文标题】:Arrays.asList() of an array 【发布时间】:2010-11-17 22:31:39 【问题描述】:这个转换有什么问题?
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()
进行排序,我只是对这个感到好奇。
【问题讨论】:
哇,感谢您的即时答复!干杯,所有:) 简短回答:因为 int[] 不可比较 【参考方案1】:让我们考虑以下简化示例:
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 arrays 的 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);
【讨论】:
您的图片链接似乎已损坏。如果您仍然有原始图像,请将其重新上传到 stack.imgur,或者只是编辑您的答案以使其在没有图像的情况下工作。谢谢。 感谢您的通知。当前版本的 IntelliJ IDEA 给出的警告与我记得的损坏图像不同(IIRC 曾经有一个Arrays.asList
特定警告),所以我编辑了答案以在没有图像的情况下工作。【参考方案2】:
您正在尝试将 int[] 转换为 Integer[],这是不可能的。
在从数组中获取列表之前,您可以使用 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);
【讨论】:
【参考方案3】:这个异常有两个原因:
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));
导致编译时错误:
找到:java.util.List【讨论】:
构造函数ArrayList(ListArrayList<int[]> f = new ArrayList<int[]>(Arrays.asList(factors));
。永远记住int[]
只是Object
的子类,所以它被允许作为泛型类型。【参考方案4】:
使用 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;
【讨论】:
+1,因为这个解决方案确实比不方便的 Collections 更适合这个问题。【参考方案5】:我认为您已经找到了一个自动装箱不起作用的示例。因为 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】:Arrays.asList(factors)
返回 List<int[]>
,而不是 List<Integer>
。由于您使用的是new ArrayList
而不是new ArrayList<Integer>
,因此不会出现编译错误,而是创建一个包含int[]
的ArrayList<Object>
,然后您将该arraylist 隐式转换为ArrayList<Integer>
。当然,当您第一次尝试使用其中一个“整数”时,您会遇到异常。
【讨论】:
【参考方案7】:这适用于 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 中没有可变参数... :-)
【讨论】:
【参考方案8】:这是来自 Java API "排序
public static void sort(List list) 根据其元素的自然顺序,将指定列表按升序排序。列表中的所有元素都必须实现 Comparable 接口。此外,列表中的所有元素必须相互可比较(即,e1.compareTo(e2) 不得为列表中的任何元素 e1 和 e2 抛出 ClassCastException)。"
这与实现 Comparable 接口有关
【讨论】:
【参考方案9】:据我了解,集合类中的排序函数只能用于对实现了可比较接口的集合进行排序。
您正在为它提供一个整数数组。 您可能应该将其包装在已知的 Wrapper 类之一中,例如 Integer。 整数实现可比较。
我已经很长时间没有从事一些严肃的 Java 工作了,但是阅读一些有关排序功能的内容会有所帮助。
【讨论】:
以上是关于数组的 Arrays.asList()的主要内容,如果未能解决你的问题,请参考以下文章