28

当我们使用 来从数组创建列表时java.util.Arrays.asList(),列表是不可变的。List我只是想知道,当(or Setor Map) 的基本目的是具有动态大小并能够随意添加、删除元素时,我们为什么要创建一个不可变列表。当我们需要一个固定大小的数据结构时,我们选择 Array,而当我们需要一个动态数据结构时,我们选择Listor SetorMap等​​等。那么拥有一个不可变列表的目的是什么?我在执行任务时遇到了这个问题。

4

4 回答 4

41

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

是和否:可以通过调用修改列表

list.set(index, element);

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

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

这就是这里的关键点:数组不是Collection。该Arrays.asList方法主要充当“数组世界”和“收藏世界”之间的“桥梁”。

例如,该Arrays.asList方法允许您将数据传递给期望 a 的方法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方法的对应物,它以相反的方向工作(尽管此方法通常涉及创建和填充一个数组,而该Arrays.asList方法只是“包装”一个数组并让它“看起来像”一List)。

于 2014-08-22T13:07:14.117 回答
4

java.util.Arrays.asList()调用return new ArrayList<>(a);,但这个 ArrayList 是 Arrays 的一个私有类,它扩展AbstractList并覆盖了一些实现。因此,期望java.util.ArrayList. 如果您查看java.util.AbstractList您会发现您可以调用 add(E e) 但不能调用很多其他方法。因此,根据当前的实现,您可以在列表底部添加一个元素,但不能更改列表的现有结构。

于 2018-12-04T10:17:25.523 回答
1

如果你打电话System.out.println(Arrays.asList("a", "b").getClass());

运行时类型是java.util.Arrays$ArrayList,

但如果你打电话System.out.println(new ArrayList<>(Arrays.asList("a", "b").getClass()));

运行时类型是java.util.ArrayList.

也许这种区别会有所帮助。

于 2022-01-06T14:39:24.653 回答
0

这是因为add()在类AbstractList中,由 Arrays java 类(内部使用)下的自定义 ArrayList(内部静态类)扩展。请注意,此 add() 方法与 java.util.ArrayList 中定义的不同,而是java.util.Arrays$ArrayList.

数组具有固定大小的属性,由 jvm 本机提供。即使 Arrays.copyOf() 使用增加的大小,例如Arrays.copyOf(arr, 10); //10 is the length,原始数组是arr= int[]{1,2} // size is two。它总是创建一个新数组,使用System.arraycopy()该数组最终调用本机方法

[静态 void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)]

请注意,上面的列表只有大小限制,如果你真的想让一个可变列表不可变,请尝试使用Collections.unmodifiableList(mutableList); Immutablility 不是 jvm 定义的概念,而是开发人员的想法。请参考https://stackoverflow.com/a/42071121/5620851https://stackoverflow.com/a/42138471/5620851

于 2017-02-12T15:17:42.777 回答