时间:2021-05-20
ArrayList底层维护的是一个动态数组,每个ArrayList实例都有一个容量。该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向 ArrayList 中不断添加元素,其容量也自动增长。
ArrayList不是同步的(也就是说不是线程安全的),如果多个线程同时访问一个ArrayList实例,而其中至少一个线程从结构上修改了列表,那么它必须保持外部同步,在多线程环境下,可以使用Collections.synchronizedList方法声明一个线程安全的ArrayList,例如:
List arraylist = Collections.synchronizedList(new ArrayList());
下面通过ArrayList的源码来分析其原理。
1、ArrayList的构造方法:ArrayList提供了三种不同的构造方法
1) ArrayList(),构造一个初始容量为 10 的空列表。
2) ArrayList(int initialCapacity),构造一个具有指定初始容量的空列表。
3) ArrayList(Collection<? extends E> c),构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
源码如下:
private transient Object[] elementData;public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; //生成一个长度为10的Object类型的数组 } public ArrayList() { this(10); //调用ArrayList(int i) }<br><br> public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); //返回包含此 collection 中所有元素的数组 size = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); //复制指定的数组,返回包含相同元素和长度的Object类型的数组 }当采用不带参数的构造方法ArrayList()生成一个集合对象时,其实是在底层调用ArrayList(int initialCapacity)这一构造方法生产一个长度为10的Object类型的数组。当采用带有集合类型参数的构造方法时,在底层生成一个包含相同的元素和长度的Object类型的数组。
2、add方法:ArrayList提供了两种添加元素的add方法
1) add(E e),将指定的元素添加到此列表的尾部。
2) add(int index, E e),将指定的元素插入此列表中的指定位置。向右移动当前位于该位置的元素(如果有)以及所有后续元素(将其索引加 1)private int size;
如果集合中添加的元素超过了10个,那么ArrayList底层会新生成一个数组,长度为原数组的1.5倍+1,并将原数组中的元素copy到新数组中,并且后续添加的元素都会放在新数组中,当新数组的长度无法容纳新添加的元素时,重复该过程。这就是集合添加元素的实现原理。
3、get方法:
1) get(int index),返回此列表中指定位置上的元素。
4、remove方法:
1) E remove(int index),移除此列表中指定位置上的元素。向左移动所有后续元素(将其索引减 1)。
2) boolean remove(Object o),移除此列表中首次出现的指定元素(如果存在)。如果列表不包含此元素,则列表不做改动,返回boolean值。
5、clone方法:
1) Object clone(),返回此ArrayList实例的浅表副本(不复制这些元素本身) 。
以上通过对ArrayList部分关键源码的分析,知道了ArrayList底层的实现原理,关于ArrayList源码有以下几点几点总结:
1) ArrayList 底层是基于数组来实现的,可以通过下标准确的找到目标元素,因此查找的效率高;但是添加或删除元素会涉及到大量元素的位置移动,效率低。
2) ArrayList提供了三种不同的构造方法,无参数的构造方法默认在底层生成一个长度为10的Object类型的数组,当集合中添加的元素个数大于10,数组会自动进行扩容,即生成一个新的数组,并将原数组的元素放到新数组中。
3) ensureCapacity方法对数组进行扩容,它会生成一个新数组,长度是原数组的1.5倍+1,随着向ArrayList中不断添加元素,当数组长度无法满足需要时,重复该过程。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文基于jdk1.8进行分析。LinkedList和ArrayList都是常用的java集合。ArrayList是数组,Linkedlist是链表,是双向链表。
由于其功能性和灵活性,ArrayList是Java集合框架中使用最为普遍的集合类之一。ArrayList是一种List实现,它的内部用一个动态数组来存储元素,因
Java中模仿源码自定义ArrayList最近看了下ArrayList的源码,抽空根据ArrayList的底层结构写了一个功能简单无泛型的自定义ArrayLsi
Java集合删除元素ArrayList实例详解AbstractCollection集合类中有一个remove方法,该方法为了适配多种不同的集合,允许删除空的元素
本文基于jdk1.8进行分析HashMap是java开发中可以说必然会用到的一个集合。本文就HashMap的源码实现进行分析。首先看一下源码中类的javadoc