关于不可变List(由Arrays.asList()创建)

时间:2014-08-22 12:52:55

标签: java arrays list collections immutablelist

当我们使用java.util.Arrays.asList()从数组创建列表时,列表是不可变的。我很想知道为什么我们想要在List(或SetMap)的基本用途具有动态大小并且能够添加时创建不可变列表,随意删除元素。当我们需要固定大小的数据结构时,我们选择数组,当我们需要动态数据结构时,我们选择ListSetMap等。那么拥有一个数据结构的目的是什么?不可变列表?我在完成任务时遇到了这个问题。

3 个答案:

答案 0 :(得分:23)

  

当我们使用java.util.Arrays.asList()从数组创建列表时,列表是可变的。

是和否:可以通过调用

修改列表
list.set(index, element);

但是列表可能 在结构上修改。这意味着无法向列表中添加元素或从列表中删除元素。原因很简单,列表仍然由数组支持,并且数组的大小可能不会改变。

  

当我们需要固定大小的可变集合时,我们选择Array

这是关键点:数组 a CollectionArrays.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/5620851https://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),但不能调用许多其他方法。因此,按照当前的实现,您可以在列表底部添加一个元素,但不能更改列表的现有结构。