简体   繁体   English

为什么Arrays.asList()返回自己的ArrayList实现

[英]Why does Arrays.asList() return its own ArrayList implementation

I recently found out that there are actually 2 different ArrayList implementations in Java (better late than never I guess...). 我最近发现在Java中实际上有两种不同的ArrayList实现(比我猜想的更好......)。

So I was wondering why does Arrays.asList(T... a) need to return a list which can not be resized ? 所以我想知道为什么Arrays.asList(T... a)需要返回一个无法调整大小的列表? If they needed an unmodifiable list why add the set(int index, E element) method then ? 如果他们需要一个不可修改的列表,那么为什么要添加set(int index, E element)方法呢?

So my general question is why not return the java.util.ArrayList from the Arrays.asList(T... a) method ? 所以我的一般问题是为什么不从Arrays.asList(T... a)方法返回java.util.ArrayList

Also what do you gain with the java.util.Arrays.ArrayList implementation ? 您还可以使用java.util.Arrays.ArrayList实现获得什么?

You asked: 您询问:

Also what do you gain with the java.util.Arrays.ArrayList implementation ? 您还可以使用java.util.Arrays.ArrayList实现获得什么?

It is because the Arrays$ArrayList returned by Arrays.asList is just a view on the original array. 这是因为Arrays.asList返回的Arrays $ ArrayList只是原始数组的一个视图。 So when the original array is changed then the view is changed too. 因此,当更改原始数组时,视图也会更改。

If one would use an real ArrayList then the elements will be copied, and a change on the orignal array would not infuence the ArrayList. 如果使用真实的ArrayList,那么将复制元素,并且对orignal数组的更改不会影响ArrayList。

The reasons to do this are quite simple: 这样做的原因很简单:

  • performance: no need to copy anyting 表现:无需复制任何内容
  • memory efficent: no second array is needed memory efficent:不需要第二个数组

The javadoc says that asList returns "a fixed-size list backed by the specified array". javadoc说asList返回“由指定数组支持的固定大小的列表”。 If you want to resize the array, you have to create a new one and copy the old data. 如果要调整阵列大小,则必须创建一个新阵列并复制旧数据。 Than the list won't be backed by the same array instance. 比列表不会由同一个数组实例支持。 The stated goal is "This method acts as bridge between array-based and collection-based APIs." 所述目标是“此方法充当基于阵列和基于集合的API之间的桥梁。” and so write-through to the underlying array is a design requirement. 因此,对底层数组的直写是一项设计要求。

They are two different classes with different behaviours. 它们是两个具有不同行为的不同类别。

The list returned when you called Arrays.asList is a thin wrapper over the array, not a copy. 调用Arrays.asList时返回的列表是数组上的瘦包装,而不是副本。 The list returned is fixed size: attempting to call add will throw an UnsupportedOperationException exception. 返回的列表是固定大小:尝试调用add将抛出UnsupportedOperationException异常。

The java.util.ArrayList on the other hand keeps its own internal copy of the data and is variable sized. 另一方面, java.util.ArrayList保留了自己的数据内部副本,并且大小可变。

Arrays.asList需要返回一个无法调整大小的列表 - 因为底层数组不能调整大小 - 但这是可修改的 - 因为允许分配给底层数组中的元素。

actually you are able to add elements to the ArrayList with add. 实际上,您可以使用add向ArrayList添加元素。 method like this : 像这样的方法:

List<String> l2= new ArrayList<String>(Arrays.asList(array1));
l2.add("blueCheese");

In my opinion you use it to get the features of a List but applying them to an Array . 在我看来,你用它来获取List的功能,但将它们应用于数组。

Two comments: 两条评论:

1, Attempting to shrink the returned array by calling the remove() method of List interface will throw an UnsupportedOperationException. 1,尝试通过调用List接口的remove()方法缩小返回的数组将抛出UnsupportedOperationException。 This is because the inner ArrayList class inside of Arrays class extends AbstractList, and the remove() method in AbstractList throws UnsupportedException. 这是因为Arrays类中的内部ArrayList类扩展了AbstractList,而AbstractList中的remove()方法抛出UnsupportedException。

Thus once the List is returned, you can overstore existing elements EITHER in the array OR in the returned List, BUT you are NOT permitted to grow the array or shrink the array. 因此,一旦返回List,您可以在数组中或在返回的List中过载现有元素EITHER,但是不允许增长数组或缩小数组。

  1. In response to: 回应:

    actually you are able to add elements to the ArrayList with add. 实际上,您可以使用add向ArrayList添加元素。 method like this : List l2= new ArrayList(Arrays.asList(array1)); 像这样的方法:List l2 = new ArrayList(Arrays.asList(array1)); l2.add("blueCheese"); l2.add( “blueCheese”);

The l2 is an independent copy of the list, so List l2 is now decoupled from the original array&List. l2是列表的独立副本,因此List l2现在与原始数组和List分离。 So blueCheese in in l2, but not in the original array/List that were backed up from each other. 所以blueCheese在l2中,但不是在彼此备份的原始数组/列表中。

-dbednar -dbednar

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM