从数组创建可变列表?

Create mutable List from array?

提问人:ericsoco 提问时间:7/26/2012 最后编辑:Mifeetericsoco 更新时间:1/2/2021 访问量:114615

问:

我有一个数组,我想变成一个 ,以便修改数组的内容。List

Stack Overflow 有很多问题/答案,这些问题/答案解决了它如何只提供底层数组的 List 视图,以及尝试操作生成的 List 通常会抛出一个 用于操作列表的方法(例如 、 等)不是由 提供的 List 实现实现的。Arrays.asList()UnsupportedOperationExceptionadd()remove()Arrays.asList()

但是我找不到如何将数组转换为可变列表的示例。我想我可以将数组和每个值循环到一个新的列表中,但我想知道是否存在一个接口来为我执行此操作。put()

爪哇岛 阵 列 列表 可变

评论


答:

172赞 Jon Skeet 7/26/2012 #1

一个简单的方法:

Foo[] array = ...;
List<Foo> list = new ArrayList<Foo>(Arrays.asList(array));

这将创建一个可变列表 - 但它将是原始数组的副本。更改列表不会更改数组。当然,您可以稍后使用 .toArray

如果你想在数组上创建一个可变视图,我相信你必须自己实现它。

评论

3赞 Timo Westkämper 12/11/2012
Arrays.asList 返回数组的视图,支持那些不影响列表大小的变异方法
1赞 Timo Westkämper 12/11/2012
@jon-skeet我知道,我只是说 Arrays.asList 为您提供了一个可变性有限的数组支持列表,如果您需要添加/删除/插入,那么 ArrayList 包装是更好的方法。
4赞 dustinevan 6/19/2018
Java 需要在所有这些静态工厂方法中明确可变性/不可变性。发现你在运行时做了一个不可变的东西,真是太可惜了。
2赞 Jon Skeet 6/19/2018
@dustinevan:文档非常清楚 IMO:“返回由指定数组支持的固定大小列表。(对返回列表的更改“直写”到数组。
1赞 dustinevan 6/20/2018
@JonSkeet不想浪费你的时间,谢谢你所做的一切。我只想投票让名称本身更清晰——我相信文档很清楚。我们中的一些人在语言之间跳舞,这在其他语言中是相当清楚的。
2赞 Sid 7/26/2012 #2
myNewArrayList = new ArrayList<>(Arrays.asList(myArray));

评论

1赞 Brent Thoenen 7/24/2019
@JonSkeet我知道您的评论来自 2012 年,我现在生活在将来,但我假设这个评论不太成立,因为我的 IDE 特别强调并说“嘿,不要用声明的类型声明这一点。你那里不需要它“?
1赞 Jon Skeet 7/24/2019
@BrentThoenen:我不明白你的评论。您是否注意到我的评论提到了修订版 1,它使用了 ,即原始类型?“使用菱形运算符让编译器计算出类型参数”和“使用原始类型”是有区别的。myNewArrayList = new ArrayList(...)
1赞 Sid 7/25/2019
我发布了这个答案,一直生活在遗忘中,@JonSkeet本人评论了我的答案。感谢布伦特的评论。
1赞 Brent Thoenen 7/26/2019
@JonSkeet啊,我的错。我没有检查您正在评论的修订版。我做了一个错误的假设,因为 2012 年的 java 也假设空菱形运算符也是一种原始类型。那是我的b.谢谢你的回答!
44赞 vsingh 10/11/2013 #3

如果您使用的是谷歌收集 API(番石榴):

Lists.newArrayList(myArray);

评论

2赞 eugene82 6/24/2015
这是最简洁的答案。谢谢。
4赞 Logan Pickup 1/3/2018
甚至 Guava 本身也建议使用其中任何一个 - 该方法的 javadoc 意味着它将被弃用,因为它不够有用。new ArrayList<>(Arrays.asList(...))
3赞 markthegrea 11/13/2020
2020 年,仍未弃用。跳进去!
6赞 Craig P. Motlin 11/19/2013 #4

如果您使用的是 Eclipse Collections(以前称为 GS Collections),则可以使用 或 .FastList.newListWith(...)FastList.wrapCopy(...)

这两种方法都采用 varargs,因此您可以内联创建数组或传入现有数组。

MutableList<Integer> list1 = FastList.newListWith(1, 2, 3, 4);

Integer[] array2 = {1, 2, 3, 4};
MutableList<Integer> list2 = FastList.newListWith(array2);

这两种方法的区别在于是否复制数组。 不复制数组,因此需要恒定的时间。如果您知道数组可能会在其他地方发生突变,则应避免使用它。newListWith()

Integer[] array2 = {1, 2, 3, 4};
MutableList<Integer> list2 = FastList.newListWith(array2);
array2[1] = 5;
Assert.assertEquals(FastList.newListWith(1, 5, 3, 4), list2);

Integer[] array3 = {1, 2, 3, 4};
MutableList<Integer> list3 = FastList.wrapCopy(array3);
array3[1] = 5;
Assert.assertEquals(FastList.newListWith(1, 2, 3, 4), list3);

注意:我是 Eclipse Collections 的提交者。

评论

1赞 Jules 3/13/2014
这是一个不错的集合 API。我见过的第一个可能会诱使我远离我自己的实现......我发现唯一似乎缺少的通常是由数组支持的排序集实现(我发现它比基于树的实现更有效,无论是对于很少修改的数据还是对于可能经常修改但通常包含少于 10 个左右元素的集合)。
15赞 MikaelF 1/28/2017 #5

这个使用 Java 8 中包含的流 API 的简单代码创建了一个包含数组元素的可变列表(或视图):

Foo[] array = ...;
List<Foo> list = Stream.of(array).collect(Collectors.toCollection(ArrayList::new));

或者,同样有效:

List<Foo> list = Arrays.stream(array).collect(Collectors.toCollection(ArrayList::new));