我想知道使用Arrays.asList
. 在我的代码中使用它时遇到问题。
另外我想知道将数组转换为数组列表(集合)而不使用的最佳方法Arrays.asList
我想知道使用Arrays.asList
. 在我的代码中使用它时遇到问题。
另外我想知道将数组转换为数组列表(集合)而不使用的最佳方法Arrays.asList
要将数组转换为 ArrayList,我会这样做:
new ArrayList<T>(Arrays.asList(myArray));
您需要将列表包装在一个新的 ArrayList 中,否则您将无法添加任何元素,因为asList()返回的列表具有固定大小。因此,您在尝试添加元素时会收到 UnsupportedOperationException。
但如果您不喜欢上述方法,您可能也想这样做:
Collections.addAll(arraylist, array);
据我所知,两者在性能方面都是等效的。
但更重要的是,使用第一种方法有什么问题?
我想知道使用 Arrays.asList 的优缺点。
主要的“优点”是:
主要的“缺点”是:
(还有一个明显的限制:您不能应用于asList
基元数组。但是无论如何转换基元数组并非易事......)
我想知道不使用 Arrays.asList 将数组转换为数组列表(集合)的最佳方法
不使用 aslist 将数组转换为列表的最简单方法是:
new ArrayList<T>(Arrays.asList(arrayOfT))
您可能会获得更好的性能:
ArrayList<T> list = new ArrayList<T>(arrayOfT.length);
Collections.addAll(list, arrayOfT);
因为ArrayList<T>(Collection<T>)
构造函数首先调用toArray()
创建一个临时数组(至少在 Java 7 中是这样)。这意味着引擎盖下有一个额外的副本。
但最重要的是,仅使用比避免使用它的任何东西都Arrays.asList
更简单、更便宜。
Arrays.asList 让您可以像查看列表一样查看数组。这意味着将来对数组的更改将影响列表,而对列表的将来更改会影响数组。这是好事还是坏事取决于您打算对 List 做什么,以及您希望它如何与数组相关联。
对于一次性使用,我肯定会选择 Arrays.asList。例如,List 有一个 toString 来显示内容,因此 System.out.println(Arrays.asList(myArray)) 可能很有用。
如果您想保留数组的快照,不受未来更改的影响,我仍然会使用 Arrays.asList,但随后会根据其结果创建一个新列表,如 @NNzz 的上一个答案所示。
除了现有的答案,特别是@Stephen C 的一个很好的答案之外,还有一个问题Arrays.asList
。
从有效的Java
Arrays.asList
从来没有设计用于将多个参数收集到一个列表中,但是当 varargs 添加到平台时,对其进行改造似乎是个好主意。因此,可以执行以下操作:
List<String> homophones = Arrays.asList("to", ""too", "two");
这种用法有效,但启用它是一个大错误。
在 1.5 版之前,这是打印数组内容的常见习惯用法:
// Obsolete idiom to print an array!
System.out.println(Arrays.asList(myArray));
这个习惯用法是必要的,因为数组从 Object 继承了它们的toString
实现,所以直接调用toString
数组会产生一个无用的字符串,例如[Ljava.lang.Integer;@3e25a5
. 该惯用语仅适用于对象引用类型的数组,但如果您不小心在基元数组上尝试了它,程序将无法编译。例如,这个程序:
public static void main(String[] args) {
int[] digits = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 4 };
System.out.println(Arrays.asList(digits));
}
将在 1.4 版中生成此错误消息:
Va.java:6: 数组中的 asList(Object[]) 不能应用于 (int[]) System.out.println(Arrays.asList(digits));
由于在 1.5 版中将 Arrays.asList改造为 varargs 方法的不幸决定,该程序现在编译时不会出现错误或警告。
从好的方面来说,用于将数组转换为字符串的Arrays.asList惯用语现在已经过时,而当前的惯用语更加健壮。同样在 1.5 版中,为Arrays类提供了完整的Arrays.toString方法(不是 varargs 方法!),专门设计用于将任何类型的数组转换为字符串。如果您使用Arrays.toString代替Arrays.asList,程序会产生预期的结果:
// The right way to print an array
System.out.println(Arrays.toString(myArray));
从 Java 8 开始,我认为创建新数组的最简单有效的方法是:
Stream.of(myArray).collect(Collectors.toList());
最好不要再使用
new ArrayList<>(Arrays.asList());
由于这是 2 倍的工作量,这会影响内存/性能下降
关于Arrays.asList,我想几乎所有人都已经解释清楚了。我想添加更多关于使用 Arrays.asList 的糟糕体验。这已经是很久以前的事了,所以在这一点上可能与某些部分无关。
在几年前的一个项目中,我总是使用 Arrays.asList,因为它更简单、更清晰的列表初始化。然后我所做的就是将 arrayList 传递给另一个方法,甚至是库。问题是某些库将 Arrays.ArrayList 视为 ArrayList。因此,当它尝试强制转换为 java.util.ArrayList 时会导致问题
List<String> arrayList = Arrays.asList(x);
ArrayList<String> arr = (ArrayList) arrayList; //this will cause error
一些映射器(例如:dozer)无法更早地读取 Arrays.asList 的方法签名,因此映射将失败。
我还在某些库上发现了一些案例,当调用某些方法时它甚至会抛出 UnsupportedOperationException,我不知道为什么。
然后我们重构了所有代码以删除 Arrays.asList 并且不再使用它。
所以一次性使用,例如仅用于打印,它仍然可以接受,但最好不要使用它来传递价值/长时间使用。