问题 java.util.Arrays中的私有静态类ArrayList - 为什么?


在java.util.Arrays中,定​​义了一个名为“ArrayList”的私有静态类。 它仅从Arrays.asList方法引用。

这样做有什么好处? 为什么不引用java.util.ArrayList呢?

代码如下:

   /**
    * @serial include
    */
      private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable

6708
2017-12-31 05:27


起源

可能重复 为什么java.util.Arrays中有一个ArrayList声明 - Mr. Polywhirl
我的年龄超过一年了:) - Aniruddh Joshi


答案:


这样做有什么好处?为什么是 java.util.ArrayList 没有提到?

一个原因是实际的实现类不是公共API细节。这样做意味着他们可以在将来更改实现类...而不会有破坏客户代码的风险。

执行此操作的另一个原因是此私有类以不同于ArrayList的方式实现某些操作。特别是涉及更改列表大小的操作需要实现以抛出异常...以便符合javadocs中指定的行为 Arrays.asList(...) 方法。

实际上,返回的列表 Arrays.asList(...) 是原始数组的包装器,而不是完整的函数列表。这有利有弊:

  • 在不利方面,某些操作不起作用。

  • 从好的方面来说,创建一个包装器要比从一个数组中创建一流列表要便宜得多。 (后者需要将数组内容复制到列表中......对于大型数组而言,这将是昂贵的。)

此外,还存在这样的问题:通过包装器可以看到对原始数组的更改(反之亦然)......如果您需要它,这可能很有用。


你在评论中问了这个问题:

a)为什么要返回不可调整大小的列表?

因为返回一个常规的可调整大小的列表需要在某个时刻复制数组内容......这很昂贵。 (如果实现延迟了复制,直到执行了大小更改操作,原始数组和列表之间的关系将很难理解。想一想......)

b)为什么不使用Collections.unmodifiableList并传递java.util.ArrayList对象?

这没有任何成就。您仍然需要将数组内容复制到 ArrayList。这个“奇怪的”行为规范的重点是 避免 需要复制。


5
2017-12-31 05:34





尽管如此 private static ArrayList class与...的名称相同 java.util.ArrayList他们的行为不同 按设计。 鉴于此,没有理由认为实现应该是同一个。

Arrays#asList() 返回由指定数组支持的固定大小的列表。 (对返回列表的更改“直写”到数组。)此方法充当基于数组的API和基于集合的API之间的桥梁。


8
2017-12-31 05:30



行为有什么不同? - Aniruddh Joshi
@ user1395908开始, Arrays.asList() 返回无法调整大小的列表。如果您阅读它,它就在文档中 ;-) - Matt Ball
如果你不读它,它甚至在文档中! - Carl Manaster
@ user1395908这意味着: asList(a).add(x) 将抛出异常(因为返回的列表是一个 固定大小 并且无法添加新项目)和 asList(a).set(n,x) 将修改 原版的 数组(按照“写入数组”)。注意 asList 键入以返回 List  接口 (其中utils.ArrayList和私有ArrayList类实现)。 - user2864740
是的..“将修改原始数组(根据”写入数组“)。”解释它。谢谢 ! - Aniruddh Joshi