从数组创建可变列表?


84

我有一个要转换为的数组List,以修改数组的内容。

堆栈溢出有大量的问题/答案的该地址Arrays.asList(),以及它如何仅提供底层阵列的列表视图,以及如何试图操纵所得列表将通常抛出UnsupportedOperationException如用来操纵列表(例如方法add()remove()等)是未由提供的List实现实现Arrays.asList()

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

Answers:


122

一种简单的方法:

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

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

如果要在数组上创建可变视图,我相信您必须自己实现。


2
Arrays.asList返回数组视图,并支持那些不影响列表大小的变异方法
TimoWestkämper2012年

1
@ jon-skeet我知道,我只是说Arrays.asList为您提供了具有有限可变性的数组支持列表,如果您需要添加/删除/插入,那么ArrayList包装是一种更好的方法。
TimoWestkämper'12

4
Java需要在所有这些静态工厂方法中明确可变性/不变性。发现您在运行时做了一件不可变的事情真是令人遗憾。
dustinevan

1
@dustinevan:文档非常清楚IMO:“返回由指定数组支持的固定大小的列表。(更改为返回列表的列表,将其写入”数组。”)
Jon Skeet

1
@JonSkeet不想浪费您的时间-感谢您所做的一切。我只是想对名称本身进行更清晰的投票-我确信文档是清晰的。我们中有些人在各种语言之间跳舞,而在其他语言中这是很明显的。
–ustinevan

21

如果您使用的是Google Collection API

Lists.newArrayList(myArray)

1
这是最简洁的答案。谢谢。
eugene82

2
甚至Guava本身也建议使用其中一种new ArrayList<>(Arrays.asList(...))-该方法的javadoc表示将不赞成使用该方法,因为它不够有用。
Logan Pickup

2020年仍未弃用。跳进去!
markthegrea

11

使用Java 8中包含的Stream 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));

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
那是一个不错的collections API。我见过的第一个可能会诱使我脱离自己的实现...我似乎普遍认为有用的唯一缺失是数组支持的排序集实现(我发现它比a效率更高)很少修改的数据或可能经常修改但通常少于10个左右的元素集的基于树的实现)。
Jules 2014年

0
myNewArrayList = new ArrayList<>(Arrays.asList(myArray));

1
@JonSkeet我知道您的评论来自2012年,现在我很满意,但是考虑到我的IDE特别强调了这一点,我认为此评论不太理想,并说:“嘿,不要用声明的类型。您在那里不需要它吗?
布伦特·托嫩

1
@BrentThoenen:我不理解你的评论。您是否注意到我的评论涉及版本1,即使用myNewArrayList = new ArrayList(...)的原始类型?“使用菱形运算符让编译器计算出类型参数”与“使用原始类型”之间有区别。
乔恩·斯基特

1
我发布了这个答案,并且一直呆在@JonSkeet自己对我的答案发表评论的过程中。感谢布伦特发表评论。
Sid

@JonSkeet啊,我不好。我没有检查您评论的修订版。我在2012 Java中也将空Diamond运算符也假定为原始类型时做出了错误的假设。那是我的b。谢谢你的回答!
布伦特·汤嫩

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.