当我们使用java.util.Arrays.asList()
从数组创建列表时,列表是不可变的。我很想知道为什么我们想要在List
(或Set
或Map
)的基本用途具有动态大小并且能够添加时创建不可变列表,随意删除元素。当我们需要固定大小的数据结构时,我们选择数组,当我们需要动态数据结构时,我们选择List
或Set
或Map
等。那么拥有一个数据结构的目的是什么?不可变列表?我在完成任务时遇到了这个问题。
答案 0 :(得分:23)
当我们使用java.util.Arrays.asList()从数组创建列表时,列表是可变的。
是和否:可以通过调用
修改列表list.set(index, element);
但是列表可能不 在结构上修改。这意味着无法向列表中添加元素或从列表中删除元素。原因很简单,列表仍然由数组支持,并且数组的大小可能不会改变。
当我们需要固定大小的可变集合时,我们选择Array
这是关键点:数组不 a Collection。 Arrays.asList
方法主要用作"桥接"在"阵列世界之间"以及"收藏世界"。
Arrays.asList
方法允许您将数据传递给期望Collection
的方法:
// A method that expects a collection:
void process(List<String> strings) { ... }
void call()
{
String array[] = new String[] { "A", "B", "C" };
// Pass the array (as a list) to the method:
process(Arrays.asList(array));
}
此应用案例包括从数组创建其他集合。例如,如果您有一个数组并且想要创建一个包含数组中元素的Set
,那么您可以
String array[] = new String[] { "A", "B", "C" };
Set<String> set = new HashSet<String>();
for (String s : array)
{
set.add(s);
}
但是使用Arrays.asList
方法,可以更方便地完成:
Set<String> set = new HashSet<String>(Arrays.asList(array));
Arrays.asList
方法可以说是Collection#toArray方法的对应方式,它的工作方向相反(尽管此方法通常涉及创建和填充 new 数组,而Arrays.asList
方法只是&#34;包装&#34;一个数组,让它看起来像&#34;一个List
)。
答案 1 :(得分:0)
这是因为类 AbstractList 中的Ioktak : 54948232518148653519995784773259
'99x\`b0x\'b : 24034969117462298298932307218853
uttuJ## : 74616072929762262275291990931711
,由Arrays java类(内部使用)下的自定义ArrayList(内部静态类)扩展。请注意,这个add()方法与java.util.ArrayList中定义的方法不同,但是add()
的方法。
数组具有固定大小的属性,由jvm本机提供。即使,Arrays.copyOf()使用的是更大的大小,例如java.util.Arrays$ArrayList
,其中原始数组为Arrays.copyOf(arr, 10); //10 is the length
。它使用arr= int[]{1,2} // size is two
创建始终是一个新数组,最终调用本机方法。
[static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)]
请注意,上面的列表只有大小限制,如果你真的想让一个可变列表不可变,请尝试使用System.arraycopy()
Immutablility不是jvm定义的概念,而是开发人员的想法。请参阅https://stackoverflow.com/a/42071121/5620851和https://stackoverflow.com/a/42138471/5620851
答案 2 :(得分:0)
java.util.Arrays.asList()
调用return new ArrayList<>(a);
,但是此ArrayList是Arrays的私有类,它扩展了AbstractList
并覆盖了某些实现。因此,期望行为java.util.ArrayList
是不公平的。如果查看java.util.AbstractList
,您会看到可以调用add(E e),但不能调用许多其他方法。因此,按照当前的实现,您可以在列表底部添加一个元素,但不能更改列表的现有结构。