答应自己的事就一定要做到
ArrayList一个经常用到的存储数据的集合;所以底层的代码是有必要的看下的.
继承和实现
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
继承了AbstractList ; 实现了List ,RandomAccess ,Cloneable 和 Serializable 序列化结合
往上看
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>
AbstractList 也是实现了List ;然后继承了AbstractCollection
继续往上看
public abstract class AbstractCollection<E> implements Collection<E>
public interface List<E> extends Collection<E>
AbstractCollection 和 List 都是继承了 Collection结合
参数部分 :
// 默认的 capacity 大小
private static final int DEFAULT_CAPACITY = 10;
// 空的数组
private static final Object[] EMPTY_ELEMENTDATA = {};
// 默认空的数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 储存数据的数组
transient Object[] elementData;
// 集合大小
private int size;
构造函数
// 给存储数据的数组默认给空的数组 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
// 给定大小的构造函数 ;
public ArrayList(int initialCapacity) { // 如果大于 0 就给存储数据的数组初始化 initialCapacity 大小 if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { // 如果等于0;默认给定空的 this.elementData = EMPTY_ELEMENTDATA; } else { // 否则就抛出异常 throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
// 给定集合的构造函数
public ArrayList(Collection<? extends E> c) { // 赋值给 elementData elementData = c.toArray(); // elementData的长度赋值给 size 并且不为0 if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) // 判断类型是不是Object数组类型;如果不是的话;就利用Arrays.copyOf();进行f复制 if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. // 这里就是给 elementData 赋值为空的数组 this.elementData = EMPTY_ELEMENTDATA; } }
一些简单的方法
// 返回size的长度 public int size() { return size; }
// 这里仅仅只是判断了集合的长度是不是0;并没有判断不为null的情况
public boolean isEmpty() { return size == 0; }
// 转化为数组;利用 Arrays.copyOf来进行转化
public Object[] toArray() { return Arrays.copyOf(elementData, size); }
// indexOf 方法;对传入进来的Object进行判断;如果是null的话;后续就使用下标来判断是否等于null;如果不是的话;就用equals来进行判断;如果都没有的话;就会返回-1
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; }
// 判断是否包含;就是调用上面的Index(o) 来进行判断;可以看出调用indexOf()后返回结果大于等于0就是正确的,也就是包含的.
public boolean contains(Object o) { return indexOf(o) >= 0; }
// 根据传入进来的数据大小判断;如果minCapacity 大于 MAX_ARRAY_SIZE (Intefer.MAX_VALUE-8)的判断; 如果大的话;就把Integer.MAX_VALUE赋值给他.否则就是MAX_ARRAY_SIZE private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } // 扩容的判断方法 private void grow(int minCapacity) { // overflow-conscious code // 获取存储数据的数组长度 int oldCapacity = elementData.length; // 对长度 1.5倍 比如oldCapacity 是10的话,那么newCapacity就是15 int newCapacity = oldCapacity + (oldCapacity >> 1); // 对newCapacity 和 minCapacity 大小判断;如果你比扩容后的大小还大,那么就把你给我 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; // 如果newCapacity 大于MAX_ARRAY_SIZE的话;就调用上面的hugeCapacity()方法返回的数值赋值给newCapacity if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: // 对数组进行阔加 elementData = Arrays.copyOf(elementData, newCapacity); }
// 判断 minCapacity 是否大于 elementData的长度;如果大于的话;就调用grow方法
private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); }
// 如果 elementData 是空的数组的话:对DEFAULT_CAPACITY 和 minCapacity 进行大小比较
private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity;
// 调用calculateCapacity 和 ensureExplicitCapacity方法
private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); }
// 判断index是否在数组的长度内;如果不在的话;就抛出异常 private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
添加,获取等方法
// 调用 ensureCapacityInternal来让存储数据的长度加一;然后新加入的一个值赋值上e;然后true表示添加成功 public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
// 根据下标来进行添加 public void add(int index, E element) { // 对下标进行检查;判断是否在集合的长度内 rangeCheckForAdd(index); // add(E e)中的方法 ensureCapacityInternal(size + 1); // Increments modCount!! // 对存储数据的数组进行赋值;从index index + 1 到 size - index的范围 System.arraycopy(elementData, index, elementData, index + 1, size - index); // 将下标的值给赋值上新要添加的值 elementData[index] = element; // 长度加一 size++; }
// 根据下标来进行赋值;也就是将该下标之前的值给覆盖掉 public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; }
// 获取下标的值E;然后return回去 E elementData(int index) { return (E) elementData[index]; }
// 先检查index是否在size范围内;然后直接调用上面的elementData()获取值 public E get(int index) { rangeCheck(index); return elementData(index); }
// 移除; 根据传递进来的o是否是null来进行移除操作 public boolean remove(Object o) { 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; }
// numMoved 就是用来进行数组copy的的范围结尾点;然后size --并将之前的size那个值=null private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work }
// 根据下标来进行删除 public E remove(int index) { // 先检查下标是否越界 rangeCheck(index); modCount++; // 获取该下标的值 E oldValue = elementData(index); // 记录数组需要arrayCopy最后的值 int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; }
// 根据size 的长度;elementData中的值一个一个的=null public void clear() { modCount++; // clear to let GC do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; }
大致的基本介绍就这里了,至于那些类似于 System.arraycopy()这种方法可以自己试用或者百度来看下具体的效果。
里面还有很多类似于迭代器;内部内都没具体的介绍出来。各位可以自寻点进去看.
下面附上去个人默认ArrayList的代码;一个很粗糙的很简单的Code
package com.yang;
import java.io.Serializable;
import java.util.Arrays;
import com.yang.exception.NumberNotLessZeroValueExcption;
/**
*
* @author Gavin write Slef Simple ArrayList
*
* @param <E>
*/
public class YangList<E> implements Serializable {
/**
* Serial Version Uid
*/
private static final long serialVersionUID = -4262254823843824598L;
/**
* 集合长度
*/
private int size;
/**
* 存储数据的集合
*/
transient Object[] elementData;
/**
* 默认空的集合
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* 空的集合
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* 默认大小
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 最大的长度
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* 构造方法
*/
public YangList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* 构造方法
* @param initialCapacity
*/
public YangList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
this.size = initialCapacity;
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new NumberNotLessZeroValueExcption("The Number Value: " + initialCapacity + " ;less zero");
}
}
/**
* 获取长度
*
* @return
*/
public int size() {
return this.size;
}
/**
* 长度的判断
*
* @return
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 添加
*
* @param e
* @return
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true;
}
/**
* 根据下标来添加
* @param index
* @param element
*/
public void add(int index,E element) {
// 检查下标是否越界
rangeCheck(index);
ensureCapacityInternal(size + 1);
System.arraycopy(elementData, index, elementData, index+1, size - index);
elementData[index] = element;
size ++;
}
/**
* 获取
*
* @param index
* @return
*/
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
/**
* 根据下标移除
* @param index
* @return
*/
public E remove(int index) {
rangeCheck(index);
E data = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0) {
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
}
elementData[--size] = null;
return data;
}
/**
* 清空
*/
public void clear() {
for (int i = 0; i < size; i++) {
elementData[i] = null;
}
size = 0;
}
/**
*
* @param minCapacity
*/
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
/**
* 确定是否扩容
* @param minCapacity
*/
private void ensureExplicitCapacity(int minCapacity) {
if (minCapacity > elementData.length) {
grow(minCapacity);
}
}
/**
*
* @param elementData
* @param minCapacity
* @return
*/
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
/**
* 扩容
* @param minCapacity
*/
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity < minCapacity) {
newCapacity = minCapacity;
}
if (newCapacity > MAX_ARRAY_SIZE) {
newCapacity = hugeCapacity(newCapacity);
}
elementData = Arrays.copyOf(elementData, newCapacity);
}
/**
* 判断minCapacity
* @param minCapacity
* @return
*/
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) {
throw new OutOfMemoryError();
}
return minCapacity > MAX_ARRAY_SIZE ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
/**
* 根据index检查出是否越界
*
* @param index
*/
private void rangeCheck(int index) {
if (index >= size || index < 0) {
throw new NullPointerException("数据有问题异常:" + index);
}
}
/**
* 根据Index获取E
*
* @param index
* @return
*/
E elementData(int index) {
return (E) elementData[index];
}
}
生命不息;奋斗不止.