我正在使用一个List
来保存通过调用Array.asList()
方法获取的一些数据。然后我尝试使用myList.Remove(int i)
方法删除一个元素。但是在尝试执行此操作时,我遇到了UnsupportedOperationException
。这是什么原因?我应该如何解决这个问题?
Array.asList()
将一个数组封装成了列表接口。该列表仍由该数组支持。数组是固定大小的,不支持添加或删除元素,因此包装器也不能实现这些功能。
文档没有像他们可能会做得那样清楚,但它们确实说:
返回由指定数组支持的固定大小列表。
"固定大小"应该是您无法添加或删除元素的提示 :)
虽然还有其他方法可以解决这个问题(使用其他方式从数组创建新的ArrayList
)而无需额外的库,但我个人建议获取Google Collections Library(或Guava,在发布时)。然后您可以使用:
List<Integer> list = Lists.newArrayList(array);
我之所以建议这样做,是因为GCL通常是一件好事,并且值得使用。
正如在评论中提到的那样,这会对数组进行复制;列表不受原始数组支持,任何集合中的更改都不会反映在另一个集合中。
它不是java.util.ArrayList
。 Arrays.asList()
返回其自己的List
实现(对数组进行的更改会“写入”到该列表中)。
它是一个固定大小的列表,因此不支持删除操作。
您可以从中创建真正的ArrayList
:
new java.util.ArrayList<>(Arrays.asList(someArray));
asList()
的工作方式确实很令人困惑,我必须承认。
返回由指定数组支持的固定大小列表。(对返回的列表所做的更改将“写入”到数组中。)
请注意,Javadocs中标记为“可选操作”的Collections.remove(int),意味着并非所有集合都支持它。“fixed-size list”表示您无法更改列表的大小,而remove()会更改大小,因此不受支持。
如果您想更改由Arrays.asList()生成的列表,请复制它,例如:new ArrayList(Arrays.asList(...))
。
从asList获取的实现不完全实现了List接口。我建议将列表转换为ArrayList,然后对其进行修改。
请参阅remove()。
因为你得到的是只读列表。 尝试:
List newList = new ArrayList(myList);
使用
ArrayList 代替 List
List 元素大小固定,无法添加或删除元素。
.asList()
方法的错误实现。它返回List
的实现,而默认情况下,List
是Dynamic Array
的实现。因此,非常奇怪的是,动态数组实现是一个固定大小的数组。 - Giorgi TsiklauriList<E>
具有可能不受所有实现支持的操作。同样,还有静态方法(List.of
和List.copyOf
)返回不可修改的列表。asList()
的行为完全按照文档说明,那么它怎么可能是“错误的实现”呢? - Jon SkeetList
实现引用类型?主要原因是要有一个实现动态数组ADT的实现,公开添加和删除元素的方法。所有流行的实现(据我所知)都实现了动态数组的想法。如果某个List实例和另一个List实例在行为上有所不同,仅仅是因为它们创建的方式不同,这给我带来了相当不稳定和不一致的印象。 - Giorgi TsiklauriList<E>
进行只读索引访问和大小可用性有很多理由。许多List<E>
的用途根本不需要它是可变的。如果有一个表达这一点的接口(例如在.NET中),那就太好了,但是List<E>
是一个非常古老的接口。 - Jon Skeet