尝试从 Array.asList 返回的列表中删除时的 UnsupportedOperationException

UnsupportedOperationException when trying to remove from the list returned by Array.asList

提问人:Chathuranga Chandrasekara 提问时间:10/26/2009 最后编辑:Vasily KabunovChathuranga Chandrasekara 更新时间:8/7/2020 访问量:26336

问:

我正在使用 a 来保存通过调用方法获得的一些数据。然后我尝试使用方法删除一个元素。但是,当我尝试这样做时,我得到了一个.这是什么原因呢?我应该如何解决这个问题?ListArray.asList()myList.Remove(int i)UnsupportedOperationException

Java 异常 列表

评论


答:

6赞 Stefan Ernst 10/26/2009 #1

从 asList 收到的实现不会实现完整的 List 接口。我会将列表转换为 ArrayList,然后对其进行修改。

参见 remove()。

评论

0赞 Chathuranga Chandrasekara 10/26/2009
你的意思是遍历这个列表并在开始时将所有对象放入 ArrayList 中??
0赞 Stefan Ernst 10/26/2009
不,ArrayList 构造函数将 Collection 作为参数,因此您可以直接调用 new ArrayList。
28赞 Carlos 10/26/2009 #2

不是. 返回它自己的实现(将更改“写入”到数组中)。java.util.ArrayListArrays.asList()List

这是一个固定大小的列表,因此不支持删除。

你可以从中创建一个真实:ArrayList

new java.util.ArrayList<>(Arrays.asList(someArray));  

我必须承认,工作方式非常令人困惑。asList()

0赞 St.Shadow 10/26/2009 #3

因为你得到的是只读列表。 尝试

List newList = new ArrayList(myList);
77赞 Jon Skeet 10/26/2009 #4

Array.asList() list 接口中包装一个数组。该列表仍由数组支持。数组是固定大小的 - 它们不支持添加或删除元素,因此包装器也不能。

文档并没有尽可能清楚地说明这一点,但他们确实说:

返回由指定数组支持的固定大小列表。

“固定大小”位应该提示您不能添加或删除元素:)

虽然还有其他方法可以解决这个问题(从数组创建新的其他方法),但没有额外的库,我个人建议获得 Google 收藏库(或番石榴,当它发布时)。然后,您可以使用:ArrayList

List<Integer> list = Lists.newArrayList(array);

我之所以提出这个建议,是因为 GCL 总体上是一件好事,非常值得使用。

如注释中所述,这需要数组的副本;原始数组不支持该列表,并且不会在另一个集合中看到任何一个集合中的更改。

评论

0赞 desau 7/17/2013
同意。但是,我认为值得注意的是,原始方法确实返回了一个由原始数组支持的列表,并将“直写”更改为原始数组。使用此选项不会返回由原始数组支持的 List,并且此返回的 List 中的任何更改都不会影响原始数组。
0赞 Giorgi Tsiklauri 6/30/2020
从意识形态上甚至语义上讲,这非常奇怪,据我所知——方法的错误实现。它返回 的实现,默认情况下,它是 的实现。所以,很奇怪的是,动态数组实现是一个固定大小的数组。.asList()ListDynamic Array
0赞 Jon Skeet 6/30/2020
@GiorgiTsiklauri:“默认情况下,它是动态数组的实现”是什么意思? 在各个位置显式记录,以具有并非所有实现都支持的操作。同样,也有静态方法 ( 和 ) 返回不可修改的列表。 行为与记录完全一样,那么它怎么可能是“错误的实现”呢?List<E>List.ofList.copyOfasList()
0赞 Giorgi Tsiklauri 6/30/2020
@JonSkeet,我的意思是,为什么世界上有人会使用实现引用类型?主要原因是要实现 ADT,公开动态添加和删除元素的方法。据我所知,它的所有流行实现都完全实现了 - 动态数组思想。如果 List 的某个实例和 List 的某个其他实例在行为上有所不同,只是因为它们的创建方式不同,这给我带来了相当不稳定和不一致的画面。ListDynamic Array
0赞 Jon Skeet 6/30/2020
@GiorgiTsiklauri:“我的意思是,为什么世界上有人会使用列表实现引用类型”。我不确定您所说的“列出实现引用类型”是什么意思,但有很多理由用于只读索引访问和大小的可用性。很多很多的用法根本不要求它是可变的。如果有一个接口来表达这一点(例如,在 .NET 中),那就太好了,但这是一个非常古老的接口。List<E>List<E>List<E>
7赞 sleske 10/26/2009 #5

请阅读 Arrays.asList() 的 API 文档:

返回由指定数组支持的固定大小列表。(对返回列表的更改 “写通”到数组。

请注意,Collections.remove(int) 在 Javadocs 中被标记为“可选操作”,这意味着并非所有 Collections 都支持它。“固定大小列表”表示您不能更改列表的大小,而 remove() 可以这样做。所以它不受支持。

如果要更改 Arrays.asList() 生成的列表,只需复制它,例如 .new ArrayList(Arrays.asList(...))

0赞 shubomb 8/20/2017 #6

ArrayList 而不是 List

列表有固定大小的元素,列表既不能添加项目,也不能删除项目