【问题标题】:private static class ArrayList in java.util.Arrays - Why?java.util.Arrays 中的私有静态类 ArrayList - 为什么?
【发布时间】:2021-09-05 08:27:20
【问题描述】:

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

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

代码如下:

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

【问题讨论】:

标签: java arraylist


【解决方案1】:

尽管private static ArrayList 类与java.util.ArrayListthey behave differently by design. 具有相同的名称,但鉴于此,没有理由认为实现应该是相同的。

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

【讨论】:

  • 行为有什么不同?
  • @user1395908 开始,Arrays.asList() 返回一个无法调整大小的列表。它就在文档中,如果您阅读它;-)
  • 我阅读了文档.. 但无法理解以下内容-a) 为什么返回不可调整大小的列表? b) 为什么不使用 Collections.unmodifiableList 并传递 java.util.ArrayList 对象?
  • @user1395908 表示:asList(a).add(x) 会抛出异常(因为返回的列表是固定大小,无法添​​加新的项),asList(a).set(n,x) 会修改original 数组(根据“写入数组”)。请注意,asList 被键入以返回 List 接口(其中 utils.ArrayList 和私有 ArrayList 类实现)。
  • 是的..“将修改原始数组(根据“写入数组”)。“解释它。谢谢!
【解决方案2】:

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

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

这样做的另一个原因是这个私有类实现了一些与 ArrayList 不同的操作。具体而言,需要实现涉及更改列表大小的操作以引发异常......以符合 Arrays.asList(...) 方法的 javadocs 中指定的行为。

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

  • 不利的一面是,某些操作不起作用。

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

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


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

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

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

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

这并没有取得任何成果。您仍然需要将数组内容复制到ArrayList。这个“奇怪”的行为规范的全部意义在于避免复制的需要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 2017-09-18
    • 1970-01-01
    • 2012-08-18
    • 1970-01-01
    相关资源
    最近更新 更多