大致思路
通过看源码ArrayList 分析:
- 核心
(1)是由线性的连续分配的内存空间, 有Object[]数组实现
(2当数组满时, 需要使用扩容机制:
-
System.arraycopy(原数组,原数组的起始复制位置,目标数组,目标数组的移动位置, 复制的容量 大小)
-
Arrays.copyOf(数组,扩容的大小) --底层使用System.arraycopy(..)方法--->实际是native本地方法修饰.
代码实现MyArrayList
测试
结果
MyArrayList 示例代码
package com.learn.arraylist;
import java.util.Arrays;
/**
* 核心: (1)是由线性的连续分配的内存空间, 有Object[]数组实现
* (2当数组满时, 需要使用扩容机制:
* System.arraycopy(原数组,原数组的起始复制位置,目标数组,目标数组的移动位置, 复制的容量 大小)
* Arrays.copyOf(数组,扩容的大小) --底层使用System.arraycopy(..)方法--->实际是native本地方法修饰.
* @author xzb
*
* @param <E>
*/
public class MyArrayList<E> {
/**初始容量大小: 默认10*/
private static final int DEFAULT_CAPACITY = 10;
/**默认容器为空*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**最大容量*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**容器存放元素*/
transient Object[] elementData;
/**元素的个数*/
private int size;
/**
* 无参
*/
public MyArrayList() {
elementData = new Object[DEFAULT_CAPACITY];
}
/**指定初始容量大小*/
public MyArrayList(int initialCapacity) {
if (initialCapacity > 0 ) {
elementData = new Object[initialCapacity];
} else if (initialCapacity == 0 ) {
elementData = new Object[DEFAULT_CAPACITY];
} else {
throw new IllegalArgumentException("初始容量必须为正数: "+
initialCapacity);
}
}
/**add方法*/
public boolean add(E e) {
// 判断是否需要扩容
ensureCapacityInternal(size + 1); // Increments modCount!!
// 添加到容器
elementData[size++] = e;
return true;
}
/**指定位置添加元素*/
public void add(int index, E element) {
// 脚标是否越界了或不存在
rangeCheckForAdd(index);
// 是否扩容
ensureCapacityInternal(size + 1); //
// 指定位置,移动元素,扩容机制
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
/**get方法*/
public E get(int index) {
/**判断元素脚标是否越界*/
rangeCheck(index);
return elementData(index);
}
/**删除下标元素*/
public E remove(int index) {
// 校验下标
rangeCheck(index);
// 获取删除的袁术
E oldValue = elementData(index);
// 删除当前元素后, index位置后的元素需要 向前移动的开始位置
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // 把最后一个元素置空
return oldValue;
}
/**指定位置替换元素*/
public E set(int index, E element) {
// 判断脚标
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
/**
* 容器的扩容 容量
* @param minCapacity
*/
private void ensureCapacityInternal(int minCapacity) {
// 扩容的容量
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
/**判断是否需要扩容*/
private void ensureExplicitCapacity(int minCapacity) {
if (minCapacity - elementData.length > 0) // 不需要扩容
grow(minCapacity);// 需要扩容
}
/**扩容*/
private void grow(int minCapacity) {
// 当前容器容量
int oldCapacity = elementData.length;
// 扩容后的容量
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0) // 防止扩容后的容量,不比之前的容量大, 比如当前容量为1, 上面扩容算法,扩容后还是1的问题
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0) // 比最大容量还大,
newCapacity = hugeCapacity(minCapacity);
// 扩容: 参数1, 扩容的原数组,参数2: 扩容的新容量大小
elementData = Arrays.copyOf(elementData, newCapacity);
}
/**是否容量内存溢出*/
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow, 比Interger的还大,, 则为负数了,此时内存不够
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
/**判断元素脚标是否越界*/
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException("脚标越界了....");
}
/**脚标越界了或不存在*/
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException("脚标越界了或不存在....");
}
/**获取角标位置元素*/
E elementData(int index) {
return (E) elementData[index];
}
/**当前容器元素个数*/
public int size() {
return size;
}
/**容器是否有元素*/
public boolean isEmpty() {
return size == 0;
}
}