【发布时间】:2011-03-28 22:23:49
【问题描述】:
ArrayList 在内部使用什么数据结构?
【问题讨论】:
ArrayList 在内部使用什么数据结构?
【问题讨论】:
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。
【讨论】:
Object[] 作为其支持数据结构。 Object[] 可以容纳任何东西。
Object[]
ArrayList 初始容量为 10。要更深入地探索,请访问codenuclear.com/how-arraylist-works-internally-java
它使用Object[],并在数组满时创建一个更大的数组。
您可以阅读source code here。
【讨论】:
ArrayList 使用对象数组在内部存储数据。
初始化 ArrayList 时,会创建一个大小为 10(默认容量)的数组,并且添加到 ArrayList 的元素实际上会添加到该数组中。 10 是默认大小,可以在初始化 ArrayList 时作为参数传递。
当添加一个新元素时,如果数组已满,则创建一个比初始大小多 50% 的新数组,并将最后一个数组复制到这个新数组中,这样现在新元素就有了空白空间被添加。
由于使用的底层数据结构是一个数组,因此向 ArrayList 添加一个新元素是相当容易的,因为它被添加到列表的末尾。当一个元素要添加到其他任何地方时,比如开头,那么所有元素都必须向右移动一个位置,以便在开头创建一个空白空间,以便添加新元素。此过程耗时(线性时间)。但是 ArrayList 的优点是在任何位置检索元素都非常快(恒定时间),因为它的基础是简单地使用对象数组。
【讨论】:
ArrayList具有基本数据结构:
private transient Object[] elementData;
当我们实际创建ArrayList 时,会执行以下代码:
this.elementData = new Object[initial capacity];
ArrayList可以通过以下两种方式创建:
List list = new ArrayList();默认构造函数被调用,并将在内部创建一个默认大小为 10 的 Object 数组。
List list = new ArrayList(5);当我们以这种方式创建ArrayList 时,会调用带有整数参数的构造函数,并且
创建一个默认大小为 5 的 Object 数组。
在add 方法中检查当前填充元素的大小是否大于/等于
ArrayList 然后它将创建新的ArrayList 大小为新的arraylist = (current arraylist*3/2)+1 并将数据从旧复制到
新数组列表。
【讨论】:
它使用一个数组和几个整数来表示第一个值 - 最后一个值的索引
private transient int firstIndex;
private transient int lastIndex;
private transient E[] array;
Here's 一个示例实现。
【讨论】:
通常,像ArrayLists 这样的结构是由一个在类中定义的老式数组实现的,并且不能在类外直接访问。
最初为列表分配了一定的空间,当你添加一个超过数组大小的元素时,数组将重新初始化一个新的容量(通常是当前大小的一些倍数,所以框架不会在添加每个新条目时不断地重新分配数组)。
【讨论】:
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;
.
.
.
}
【讨论】:
ArrayLists 使用数组来保存数据。一旦元素的数量超过分配的数组,它就会将数据复制到另一个数组,可能是两倍的大小。
复制数组时会对性能造成(轻微)影响,因此可以在数组列表的构造函数中设置内部数组的大小。
此外,它还实现了java.util.Collection 和java.util.list,因此可以获取指定索引处的元素,并且可以迭代(就像数组一样)。
【讨论】:
它使用一个对象[]。当数组已满时,它会创建一个大小增加 50% 的新数组,并将当前元素复制到新数组中。它自动发生。
【讨论】:
据我了解
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的工作原理
【讨论】:
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.
【讨论】: