1

我想知道使用Arrays.asList. 在我的代码中使用它时遇到问题。

另外我想知道将数组转换为数组列表(集合)而不使用的最佳方法Arrays.asList

4

5 回答 5

6

要将数组转换为 ArrayList,我会这样做:

new ArrayList<T>(Arrays.asList(myArray));

您需要将列表包装在一个新的 ArrayList 中,否则您将无法添加任何元素,因为asList()返回的列表具有固定大小。因此,您在尝试添加元素时会收到 UnsupportedOperationException。

但如果您不喜欢上述方法,您可能也想这样做:

Collections.addAll(arraylist, array);

据我所知,两者在性能方面都是等效的。


但更重要的是,使用第一种方法有什么问题?

于 2012-11-14T08:02:59.710 回答
2

我想知道使用 Arrays.asList 的优缺点。

主要的“优点”是:

  • 它不涉及复制数据,
  • 您的列表将看到在支持数组中所做的任何更改(如果需要)

主要的“缺点”是:

  • 您不能通过“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简单、更便宜。

于 2012-11-14T08:24:11.780 回答
1

Arrays.asList 让您可以像查看列表一样查看数组。这意味着将来对数组的更改将影响列表,而对列表的将来更改会影响数组。这是好事还是坏事取决于您打算对 List 做什么,以及您希望它如何与数组相关联。

对于一次性使用,我肯定会选择 Arrays.asList。例如,List 有一个 toString 来显示内容,因此 System.out.println(Arrays.asList(myArray)) 可能很有用。

如果您想保留数组的快照,不受未来更改的影响,我仍然会使用 Arrays.asList,但随后会根据其结果创建一个新列表,如 @NNzz 的上一个答案所示。

于 2012-11-14T08:07:04.627 回答
1

除了现有的答案,特别是@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));
于 2017-12-17T09:11:33.440 回答
0

从 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 并且不再使用它。

所以一次性使用,例如仅用于打印,它仍然可以接受,但最好不要使用它来传递价值/长时间使用。

于 2018-07-12T08:08:40.907 回答