【问题标题】:Initial size() of new ArrayList新 ArrayList 的初始 size()
【发布时间】:2019-03-24 09:43:40
【问题描述】:

如果我有以下情况:

List<String> list = new ArrayList<>(Arrays.asList("a","b","c"));

然后调用:

System.out.println(list.size());

它将按预期打印 3。

size() 方法的代码就是return size;,其中sizeprivate int

所以我想知道 size 变量的实际设置位置。

我看到它正在调用构造函数public ArrayList(Collection&lt;? extends E&gt; c),这很好,但是当我调试到那里并将鼠标悬停在c 上时,它已经显示size = 3

那么是Collection&lt;? extends E&gt; c 中的某些东西将其设置为3,它到达ArrayList 构造函数之前?

【问题讨论】:

  • c == 3 是什么意思?这是一个集合,而不是一个 int。
  • 哇,大量反对票。 @MuratKaragöz 当我调试该构造函数并将鼠标悬停在c 上时,它显示size = 3。我认为这是一个有效的问题。
  • 哇,强烈反对 - 也强烈赞成。对于您只需查看来源即可回答的问题,我会满足于 0 的余额
  • @achAmháin 也许某些 IDE 功能让您感到困惑?类似于我在答案中发布的图像。它不时发生在我身上;)

标签: java arraylist


【解决方案1】:

(...) 我想知道 size 变量的实际设置位置

你调用了ArrayList中的this constructor,其中source code我们可以看到size = elementData.length;

public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    size = elementData.length; // <-- HERE
    if (elementData.getClass() != Object[].class)
        elementData = Arrays.copyOf(elementData, size, Object[].class);
}

因此,一旦调用 size() (source code),该值就已经设置好了。


当我调试到那里并将鼠标悬停在 c 上时,它已经显示 size = 3

如果您指的是类似于下图的内容...我认为它可能是一些 IDE 功能(例如在我的 IntelliJ IDEA 的情况下),它可以推断出c (List) 的特定类型和计算它的大小。


(...) 是在 Collection&lt;? extends E&gt; c 中将其设置为 3,然后才到达 ArrayList 构造函数?

记住Arrays.asList 返回一个ListArrayList 的构造函数将其作为Collection,它也有一个size 方法。 IDE 可以使用它来计算 size 值。


PS:源代码可能会因特定 jdk 版本与其他版本略有不同。

【讨论】:

    【解决方案2】:

    它发生在你初始化新的 ArrayList 时;在构造函数中,可以看到列表的大小设置为你传入的数组的大小:

    /**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     *
     * @param c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }
    

    所以特别是if ((size = elementData.length) != 0) 将大小(您所说的私有字段)设置为传递给构造函数的数组的长度。

    【讨论】:

    • 谢谢。不知何故,我误读了那条线,所以开始寻找它在其他地方设置 size 的位置。
    【解决方案3】:

    它说它已经是 3,因为这是您作为参数传递给 new ArrayList&lt;&gt;(Arrays.asList("a","b","c"));Arrays.asList("a","b","c") 的大小。

    来源:

    public ArrayList(Collection<? extends E> c) {
        // c is already instantiated here 
        elementData = c.toArray();
        // ...
    }
    

    【讨论】:

      【解决方案4】:

      这里,大小设置在 ArrayList 的构造函数的下一行。

      if ((size = elementData.length) != 0) {
      

      详细信息在这个其他 SO 线程中得到了很好的解释 Details

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-19
        • 2012-02-12
        • 2018-03-15
        • 1970-01-01
        • 2014-03-08
        • 1970-01-01
        • 2018-09-04
        • 2015-06-28
        相关资源
        最近更新 更多