当前位置 : 主页 > 编程语言 > java >

Java ArrayList 源码

来源:互联网 收集:自由互联 发布时间:2022-06-30
Java ArrayList 源码 ArrayList 概述 ArrayList 是基于数组实现,是一个动态数组,容量可以自动增长,动态增加内存。 ArrayList 不是线程安全的,只能用在单线程,多线程换成环境下可以考虑

Java ArrayList 源码

ArrayList 概述

ArrayList 是基于数组实现,是一个动态数组,容量可以自动增长,动态增加内存。

ArrayList 不是线程安全的,只能用在单线程,多线程换成环境下可以考虑 Collections.synchronizedList(List l) 函数返回一个线程安全的 ArrayList 类,也可以在 concurrent 并发包下的 CopyOnWriteArrayList 类。

ArrayList 实现了Serializable 接口,支持序列化传输,实现了 RandomAccess 即可,支持快速随机访问,实际上就是通过下标序号进行快速访问,实现 Cloneabale接口,可以被克隆。

每个 ArrayList 实例都有一个容量,该容量是指用例存储列表元素的数组大小,总是至少等于列表的大小,随着向ArrayList 不断添加元素,其容量会自动增长会带来数据向新数组的重新拷贝。

Collection  是 List,Set,Queue 的基础接口

Java ArrayList 源码_数组

ArrayList 属性

  • 私有属性

ArrayList 定义只定义类有私有属性

private static final long serialVersionUID = 8683452581122892189L; // 使用serialVersionUID验证版本一致性
private static final int DEFAULT_CAPACITY = 10; // 容量的初始大小
private static final Object[] EMPTY_ELEMENTDATA = {}; // Shared empty array instance used for empty instances.
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // Shared empty array instance used for default sized empty instances.
// ArrayList数据的存储之地
transient Object[] elementData; // 存储ArrayList中元素的数组
// ArrayList存储数据的个数
private int size;

elementData 存储 ArrayList 内的元素, size 标识它包含的元素的数量。

transient 的属性在对象呗序列化后不会被保存。

ArrayList 提供了三种方式的构造器,可以构造一个默认初始化为 10 的空列表,构造一个指定初始化容量的空列表与构造一个包含指定的 Collection 元素列表,这些按照 Collection 的迭代器返回他们的顺序排列。

public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}

通过传入 initialCapacity 的大小构造 ArrayList

使用初始容量构造 ArrayList

public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

使用传入指定集合构造 ArrayList

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;
}
}

方法

主要方法是增加,或者删除,修改,查找方法。

增加元素操作

public boolean add(E e)
{
// 1、确保容量大小
ensureCapacityInternal(size + 1); // Increments modCount!!
// 2、尾部添加元素
elementData[size++] = e;
return true;
}

指定位置添加元素

public void add(int index, E element)
{
// 1、检验索引
rangeCheckForAdd(index);
// 2、确保容量
ensureCapacityInternal(size + 1); // Increments modCount!!
// 3、将数据后移
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
// 4、添加元素
elementData[index] = element;
// 5、数组元素个数加1
size++;
}

在尾部添加某类集合的所有元素

public boolean addAll(Collection<? extends E> c)
{
// 1、暂存集合c中数据
Object[] a = c.toArray();
int numNew = a.length;
// 2、确保容量
ensureCapacityInternal(size + numNew); // Increments modCount
// 3、尾部添加数据
System.arraycopy(a, 0, elementData, size, numNew);
// 4、数组元素个数更新
size += numNew;
return numNew != 0;
}

指定位置添加某类集合所有元素

public boolean addAll(int index, Collection<? extends E> c)
{
// 1、检验索引
rangeCheckForAdd(index);
// 2、暂存数据
Object[] a = c.toArray();
int numNew = a.length;
// 3、确保容量
ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index;
// 4、数据后移
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
// 5、添加元素
System.arraycopy(a, 0, elementData, index, numNew);
// 6、数组元素个数更新
size += numNew;
return numNew != 0;
}

删除元素操作

删除 ArrayList 第一个符合条件的元素

public boolean remove(Object o)
{
// 移除值为null的元素
if (o == null)
{
for (int index = 0; index < size; index++)
if (elementData[index] == null)
{
fastRemove(index);
return true;
}
}
else // 移除元素
{
for (int index = 0; index < size; index++)
if (o.equals(elementData[index]))
{
fastRemove(index);
return true;
}
}
// 值不存在时,移除失败
return false;
}

其中 fastRemove 方法是采用的数组copy 方法。

private void fastRemove(int index)
{
// 1、修改的次数更新
modCount++;
int numMoved = size - index - 1;
// 2、数据前移
if (numMoved > 0)
System.arraycopy(elementData, index + 1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}

删除 ArrayList 中指定位置上的元素

public E remove(int index)
{
// 1、检验索引
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
// 2、数据前移
if (numMoved > 0)
System.arraycopy(elementData, index + 1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}

删除 ArrayList 中所包含集合中所有元素

public boolean removeAll(Collection<?> c)
{
Objects.requireNonNull(c);
return batchRemove(c, false);
}

删除某个范围的数据

是直接置空的

protected void removeRange(int fromIndex, int toIndex)
{
modCount++;
int numMoved = size - toIndex;
System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved);
// clear to let GC do its work
int newSize = size - (toIndex - fromIndex);
for (int i = newSize; i < size; i++)
{
elementData[i] = null;
}
size = newSize;
}

删除 ArrayList 中不是所传入集合的所有数据

public boolean retainAll(Collection<?> c)
{
Objects.requireNonNull(c);
return batchRemove(c, true);
}

修改操作

修改指定位置上的元素

public E set(int index, E element)
{
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}

查找操作

获取指定位置上的元素

public E get(int index) {
rangeCheck(index);
checkForComodification();
return ArrayList.this.elementData(offset + index);
}

获取指定元素在列表的第一个位置索引

public int indexOf(Object o)
{
if (o == null)
{
for (int i = 0; i < size; i++)
if (elementData[i] == null)
return i;
} else
{
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}

获取指定元素在列表中的最后一个位置索引

public int lastIndexOf(Object o) {
if (o == null) {
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}

返回某个范围的视图

public List<E> subList(int fromIndex, int toIndex)
{
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, 0, fromIndex, toIndex);
}

迭代器

public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;

public boolean hasNext() {
return cursor != size;
}

@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}

public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();

try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}

@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}

final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}

listIterator 方法

public ListIterator<E> listIterator(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index);
return new ListItr(index);
}

状态操作

是否为空

public boolean isEmpty()
{
return size == 0;
}

清空列表元素

public void clear()
{
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}

克隆 ArrayList 实例副本

public Object clone()
{
try
{
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e)
{
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}

判断是否包含某个指定元素

public boolean contains(Object o)
{
return indexOf(o) >= 0;
}

获取元素个数

public int size()
{
return size;
}

转换成数组

public Object[] toArray()
{
return Arrays.copyOf(elementData, size);
}

转换

public <T> T[] toArray(T[] a)
{
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}

还有几个问题等解决

  • fail-fast 机制
  • 序列化问题
  • 遍历效率问题

参考资料


欢迎关注公众号:程序员开发者社区

Java ArrayList 源码_数组_02

关注我们,了解更多


网友评论