【问题标题】:How does ArrayList work?ArrayList 是如何工作的?
【发布时间】:2011-03-28 22:23:49
【问题描述】:

ArrayList 在内部使用什么数据结构?

【问题讨论】:

  • 提示:JDK 是开源的。
  • Grep code 有在线可用的资源
  • 不仅是开源的,而且从第一天就公开了。(提示:JDK 中的 src.zip。)

标签: java arraylist


【解决方案1】:

ArrayList 在内部使用Object[]

当您向ArrayList 添加项目时,列表会检查后备数组是否还有剩余空间。如果有空间,则将新项目添加到下一个空白空间。如果没有空间,则创建一个更大的新数组,并将旧数组复制到新数组中。

现在,还有更多空间,新元素被添加到下一个空白处。

因为人们真的很喜欢源代码:

/**
 * The array buffer into which the elements of the ArrayList are stored.
 * The capacity of the ArrayList is the length of this array buffer.
 */
private transient Object[] elementData;

直接脱离 JDK。

【讨论】:

  • 但是数组具有相同数据类型的值,而arrayList可以存储不同的数据类型
  • @AutoMEta,它只是有一个Object[] 作为其支持数据结构。 Object[] 可以容纳任何东西。
  • @AutoMEta,这是因为后备数组是Object[]
  • ArrayList 初始容量为 10。要更深入地探索,请访问codenuclear.com/how-arraylist-works-internally-java
【解决方案2】:

它使用Object[],并在数组满时创建一个更大的数组。

您可以阅读source code here

【讨论】:

【解决方案3】:

ArrayList 使用对象数组在内部存储数据。

初始化 ArrayList 时,会创建一个大小为 10默认容量)的数组,并且添加到 ArrayList 的元素实际上会添加到该数组中。 10 是默认大小,可以在初始化 ArrayList 时作为参数传递。

当添加一个新元素时,如果数组已满,则创建一个比初始大小多 50% 的新数组,并将最后一个数组复制到这个新数组中,这样现在新元素就有了空白空间被添加。

由于使用的底层数据结构是一个数组,因此向 ArrayList 添加一个新元素是相当容易的,因为它被添加到列表的末尾。当一个元素要添加到其他任何地方时,比如开头,那么所有元素都必须向右移动一个位置,以便在开头创建一个空白空间,以便添加新元素。此过程耗时(线性时间)。但是 ArrayList 的优点是在任何位置检索元素非常快(恒定时间),因为它的基础是简单地使用对象数组。

【讨论】:

  • 谢谢,这个信息对于人们弄清楚当你添加 4000 个元素时 ArrayList 的大小如何扩展非常有用......不知道它每次都会使最初的 10 个加倍满了。
【解决方案4】:

ArrayList具有基本数据结构:

private transient Object[] elementData;

当我们实际创建ArrayList 时,会执行以下代码:

 this.elementData = new Object[initial capacity];

ArrayList可以通过以下两种方式创建:

  1. List list = new ArrayList();

默认构造函数被调用,并将在内部创建一个默认大小为 10 的 Object 数组。

  1. List list = new ArrayList(5);

当我们以这种方式创建ArrayList 时,会调用带有整数参数的构造函数,并且 创建一个默认大小为 5 的 Object 数组。

add 方法中检查当前填充元素的大小是否大于/等于 ArrayList 然后它将创建新的ArrayList 大小为新的arraylist = (current arraylist*3/2)+1 并将数据从旧复制到 新数组列表。

【讨论】:

    【解决方案5】:

    它使用一个数组和几个整数来表示第一个值 - 最后一个值的索引

    private transient int firstIndex;
    
    private transient int lastIndex;
    
    private transient E[] array;
    

    Here's 一个示例实现。

    【讨论】:

      【解决方案6】:

      通常,像ArrayLists 这样的结构是由一个在类中定义的老式数组实现的,并且不能在类外直接访问。

      最初为列表分配了一定的空间,当你添加一个超过数组大小的元素时,数组将重新初始化一个新的容量(通常是当前大小的一些倍数,所以框架不会在添加每个新条目时不断地重新分配数组)。

      【讨论】:

        【解决方案7】:

        Java platform source code 是免费提供的。摘录如下:

        public class ArrayList<E> extends AbstractList<E>
          implements List<E>, RandomAccess, Cloneable, java.io.Serializable
        {
          /**
           * The array buffer into which the elements of the ArrayList are stored.
           * The capacity of the ArrayList is the length of this array buffer.
           */
          private transient E[] elementData;
          .
          .
          .
        }
        

        【讨论】:

          【解决方案8】:

          ArrayLists 使用数组来保存数据。一旦元素的数量超过分配的数组,它就会将数据复制到另一个数组,可能是两倍的大小。

          复制数组时会对性能造成(轻微)影响,因此可以在数组列表的构造函数中设置内部数组的大小。

          此外,它还实现了java.util.Collectionjava.util.list,因此可以获取指定索引处的元素,并且可以迭代(就像数组一样)。

          【讨论】:

            【解决方案9】:

            它使用一个对象[]。当数组已满时,它会创建一个大小增加 50% 的新数组,并将当前元素复制到新数组中。它自动发生。

            【讨论】:

            • 您能否添加任何引用来支持您所说的内容?
            【解决方案10】:

            据我了解

            ArrayList 类实现 List 接口和 (因为接口只扩展了其他接口) List 接口扩展了 Collection 接口。 当我们在内存中初始化时谈论arraylist时,它默认保留空间10 >并创建您通常使用的整数数组。当此数组已满时,将创建另一个大于默认大小的整数数组。

            List<Integer> list = new ArrayList<>();
            

            现在在内存中 => Integer[] list = new Integer[10];

            现在假设您输入 1,2,3,4,5,6,7,8,9,10 数组现在已满,当您在内存中输入 11 另一个数组时会发生什么创建的整数大于默认值,旧数组中的所有元素都复制到新数组中。内部 arraylist 用户 Object[] 数组。

            这就是arrayList的工作原理

            【讨论】:

              【解决方案11】:

              ArrayList 中使用的基本数据结构是——

              private transient Object[] elementData;
              

              所以,通过声明它是一个 Object 数组。 当我们实际创建一个 arrayList 时,会执行一段代码 -

              this.elementData=new Object[initial capacity];
              

              当我们创建一个 ArrayList 时,会调用默认构造函数,并在内部创建一个默认大小为 10 的 Object 数组。现在,众所周知,与普通数组不同,ArrayList 的大小是动态增长的。但是它的大小是如何在内部增长的呢?

              所以内部发生的事情是创建一个大小为 1.5 x currentSize 的新数组,并将旧数组中的数据复制到这个新数组中。每次达到最大容量的 ArrayList 时,复制并销毁先前的数组,以新容量(1.5 x 旧容量)创建新数组。

              更多详情可以阅读my blog here.

              【讨论】:

                猜你喜欢
                • 2013-03-08
                • 2013-12-07
                • 1970-01-01
                • 1970-01-01
                • 2014-06-08
                • 1970-01-01
                • 2017-11-19
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多