当我们使用 来从数组创建列表时java.util.Arrays.asList()
,列表是不可变的。List
我只是想知道,当(or Set
or Map
) 的基本目的是具有动态大小并能够随意添加、删除元素时,我们为什么要创建一个不可变列表。当我们需要一个固定大小的数据结构时,我们选择 Array,而当我们需要一个动态数据结构时,我们选择List
or Set
orMap
等等。那么拥有一个不可变列表的目的是什么?我在执行任务时遇到了这个问题。
4 回答
当我们使用 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
)。
java.util.Arrays.asList()
调用return new ArrayList<>(a);
,但这个 ArrayList 是 Arrays 的一个私有类,它扩展AbstractList
并覆盖了一些实现。因此,期望java.util.ArrayList
. 如果您查看java.util.AbstractList
您会发现您可以调用 add(E e) 但不能调用很多其他方法。因此,根据当前的实现,您可以在列表底部添加一个元素,但不能更改列表的现有结构。
如果你打电话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
.
也许这种区别会有所帮助。
这是因为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/5620851和https://stackoverflow.com/a/42138471/5620851