Arrays.asList(T... a)有效地T[]将匹配任何真实对象数组(的子类Object)的 a 作为数组。唯一不匹配的是基元数组,因为基元类型不是从Object. 所以 anint[]不是Object[].
然后发生的事情是 varags 机制启动并将其视为您传递了单个对象,并创建了该类型的单个元素数组。因此,您传递了一个int[][](此处T为 is int[])并最终得到一个 1 元素List<int[]>,这不是您想要的。
不过,您仍然有一些不错的选择:
番石榴的Int.asList(int[])适配器
如果您的项目已经使用了番石榴,那么它就像使用 Guava 提供的适配器一样简单: Int.asList()。关联类中的每个原始类型都有一个类似的适配器,例如Booleansforboolean等。
int foo[] = {1,2,3,4,5};
Iterable<Integer> fooBar = Ints.asList(foo);
for(Integer i : fooBar) {
System.out.println(i);
}
这种方法的优点是它在现有数组周围创建了一个瘦包装器,因此包装器的创建是常数时间(不依赖于数组的大小),并且所需的存储量只是一个很小的常数(小于 100 字节)以及底层整数数组。
缺点是访问每个元素需要对底层进行装箱操作int,设置需要拆箱。如果您频繁访问列表,这可能会导致大量的临时内存分配。如果您平均多次访问每个对象,则最好使用将对象装箱一次并将它们存储为Integer. 下面的解决方案就是这样做的。
Java 8 内部流
在 Java 8 中,您可以使用该Arrays.stream(int[])方法将int数组转换为Stream. 根据您的用例,您可以直接使用流,例如,对每个元素使用forEach(IntConsumer). 在这种情况下,此解决方案非常快,根本不会产生任何装箱或拆箱,并且不会创建底层数组的任何副本。
或者,如果你真的需要一个List<Integer>,你可以stream.boxed().collect(Collectors.toList())按照这里的建议使用。这种方法的缺点是它完全装箱了列表中的每个元素,这可能会增加它的内存占用近一个数量级,它会创建一个新Object[]的来保存所有装箱的元素。如果您随后大量使用列表并需要Integer对象而不是ints,这可能会得到回报,但需要注意这一点。