Java ArrayList源码深度解析:揭秘其内部实现与优化技巧

一、ArrayList简介
ArrayList是Java集合框架中的一种常用数据结构,它实现了List接口,可以存储任意类型的对象。ArrayList基于动态数组实现,具有可变长度,能够动态扩容。在Java开发中,ArrayList被广泛应用于各种场景,如存储对象列表、实现栈、队列等。
二、ArrayList源码分析
1. 类定义
```java
public class ArrayList
{
private static final long serialVersionUID = 8683452581122892189L;
private static final int DEFAULT_CAPACITY = 10;
private transient Object[] elementData;
private int size;
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ARRAY;
}
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ARRAY;
} else {
throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
}
}
public ArrayList(Collection extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray() returns an array of "Object[]", so we need to trim the reference type
if (elementData.getClass() != Object[].class) {
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
} else {
this.elementData = EMPTY_ARRAY;
}
}
}
```
2. 扩容机制
ArrayList的扩容机制是其核心之一。当向ArrayList添加元素时,如果数组已满,则会进行扩容。以下是扩容的源码:
```java
public void add(E e) {
modCount++;
int oldCapacity = elementData.length;
if (size == oldCapacity) {
int newCapacity = oldCapacity + (oldCapacity >> 1) + 1;
Object[] newElementData = new Object[newCapacity];
System.arraycopy(elementData, 0, newElementData, 0, size);
elementData = newElementData;
}
elementData[size++] = e;
}
```
从上述代码可以看出,ArrayList在扩容时会将原数组长度增加50%,然后创建一个新的数组,并将原数组中的元素复制到新数组中。这种方式保证了ArrayList的插入操作在数组已满的情况下仍能保持较好的性能。
3. 查找与删除操作
ArrayList的查找与删除操作主要依赖于数组的线性查找。以下是查找操作的源码:
```java
public E get(int index) {
rangeCheck(index);
return (E) elementData[index];
}
public E set(int index, E element) {
rangeCheck(index);
E oldValue = (E) elementData[index];
elementData[index] = element;
return oldValue;
}
```
删除操作如下:
```java
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0) {
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
}
elementData[--size] = null;
return oldValue;
}
```
4. 线程安全
ArrayList不是线程安全的,如果需要在多线程环境下使用,可以考虑使用CopyOnWriteArrayList或Collections.synchronizedList等方法来保证线程安全。
三、总结
本文深入分析了Java ArrayList的源码,包括其类定义、扩容机制、查找与删除操作以及线程安全等方面。通过阅读源码,我们可以更好地理解ArrayList的内部实现,从而在实际开发中更好地运用它。同时,了解ArrayList的优缺点,有助于我们在选择合适的数据结构时做出明智的决策。





