我希望此代码显示true
:
int[] array = {1, 2};
System.out.println(Arrays.asList(array).contains(1));
答案 0 :(得分:36)
方法Arrays.asList(T ...)
是,当擦除泛型并变换varargs时,实际上等于Arrays.ofList(Object[])
类型的方法(二进制等价,同一方法的JDK 1.4版本)。
基元数组是Object
(另请参阅this question),但不是Object[]
,因此编译器认为您正在使用varargs版本并在您的周围生成一个Object数组int数组。您可以通过添加额外步骤来说明正在发生的事情:
int[] array = {1, 2};
List<int[]> listOfArrays = Arrays.asList(array);
System.out.println(listOfArrays.contains(1));
这会编译并等同于您的代码。它显然也会返回错误。
编译器将varargs调用转换为具有单个数组的调用,因此调用期望带参数T ...
的参数T t1, T t2, T t3
的varargs方法等同于使用new T[]{t1, t2, t3}
调用它,但特殊情况这里是如果方法需要一个对象数组,那么在创建数组之前,带有基元的varargs将被自动装箱。因此编译器认为int数组作为单个Object传入,并创建一个Object[]
类型的单个元素数组,并传递给asList()
。
所以这里再次讨论上面的代码,编译器在内部实现它的方式:
int[] array = {1, 2};
// no generics because of type erasure
List listOfArrays = Arrays.asList(new Object[]{array});
System.out.println(listOfArrays.contains(1));
以下是使用int值调用Arrays.asList()
的一些好方法和坏方法:
// These versions use autoboxing (which is potentially evil),
// but they are simple and readable
// ints are boxed to Integers, then wrapped in an Object[]
List<Integer> good1 = Arrays.asList(1,2,3);
// here we create an Integer[] array, and fill it with boxed ints
List<Integer> good2 = Arrays.asList(new Integer[]{1,2,3});
// These versions don't use autoboxing,
// but they are very verbose and not at all readable:
// this is awful, don't use Integer constructors
List<Integer> ugly1 = Arrays.asList(
new Integer(1),new Integer(2),new Integer(3)
);
// this is slightly better (it uses the cached pool of Integers),
// but it's still much too verbose
List<Integer> ugly2 = Arrays.asList(
Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)
);
// And these versions produce compile errors:
// compile error, type is List<int[]>
List<Integer> bad1 = Arrays.asList(new int[]{1,2,3});
// compile error, type is List<Object>
List<Integer> bad2 = Arrays.asList(new Object[]{1,2,3});
<强>参考:强>
Arrays.asList(T ...)
但要以一种简单的方式实际解决问题:
Apache Commons / Lang中有一些库解决方案(参见Bozho's answer)和Google Guava:
Ints.contains(int[], int)
检查一个int数组是否包含给定的int Ints.asList(int ...)
从int数组创建一个整数列表答案 1 :(得分:14)
Arrays.asList(array)
将生成int[]
的单例列表。
如果您将int[]
更改为Integer[]
,它会按预期运行。不知道这对你有帮助吗。
答案 2 :(得分:5)
Arrays.asList(ArrayUtils.toObjectArray(array))
(ArrayUtils
来自commons-lang)
但是如果你只想打电话给contains
,那就不需要了。只需使用Arrays.binarySearch(..)
(先排序数组)
答案 3 :(得分:1)
此
System.out.println(Arrays.asList(array).contains(array));
返回true
。
答案 4 :(得分:1)
您对Arrays.asList(T... a)
的理解似乎是错误的。你不会是第一个对其运作方式做出假设的人。
尝试
System.out.println(Arrays.asList(1, 2).contains(1));
答案 5 :(得分:1)
在这种情况下,Autoboxing无法按照您希望的方式运行。以下代码可能有点冗长,但是将int数组转换为列表的工作是:
List<Integer> list = new ArrayList<Integer>(array.length);
for (int value : array) {
list.add(value);
}
答案 6 :(得分:1)
以下代码显示为true:
Integer[] array = {1, 2};
System.out.println(Arrays.asList(array).contains(1));
(你的版本失败了,因为Int不是对象,但是Int []是一个对象。因此你将调用asList(T ... a),其中一个元素是一个集合,因为它不可能有一个集合a。)中
答案 7 :(得分:0)
致电时
Arrays.asList(array)
在你的基元数组上,你得到一个包含一个对象的List实例:一个int值数组!你必须先将基元数组转换成一个对象数组,正如@Bozho在他的回答中所建议的那样。
答案 8 :(得分:0)
如果您只想检查数组是否包含某些元素,只需迭代数组并搜索元素。这将需要o(n / 2)。所有其他解决方案效果较差。将数组复制到列表的任何方法都必须遍历数组,因此此操作只需要n个原子赋值。
答案 9 :(得分:-1)
我不认为你可以使用方法调用。试试这个
List<Integer> list = new ArrayList<Integer>();
for (int index = 0; index < array.length; index++)
{
list.add(array[index]);
}