Java容器之ArrayList源码总结
本次学习基于JDK1.7版本,目的在于对常用的容器类进行深入学习,加深理解,以便工作中更好的使用。
容器基本概念
Java容器类类库的用途是“保存对象”,并划分为两个不同的概念:
1、Collection保存单一的元素。
2、Map保存相关联的键值对。
容器不能持有基本类型(8种),但自动包装机制会执行基本类型到容器中所持有的包装器类型之间的双向转换。
自定义接口及对应的实现类
以下所有自定义类参考源码并做了一定处理,保留下重要的部分,用于参考理解容器内部的数据结构和功能实现,但是在完整性和严谨性上有所欠缺。
迭代器Iterator
Iterable接口中持有Iterator迭代器
package gemme.collection;
/**
* 自定义的Iterable接口
* */
public interface IMyIterable<T> {
IMyIterator<T> myIterator();
}
迭代器是一个对象,它的工作是遍历并选择序列中的对象,同时它也被称为“轻量级对象”,创建它的代价小。Iterator只能单向移动。
package gemme.collection;
/**
* 自定义迭代器
* */
public interface IMyIterator<E> {
// 下一个元素是否存在
boolean hasNext();
// 获取下一个元素
E next();
// 移除本元素
void remove();
}
Iterator的真正威力在于能够将遍历序列的操作与序列底层的结构分离。迭代器统一了对容器的访问方式。
接口Collection和抽象类AbstractCollection
自定义IMyCollection接口仿照java.util.Collention接口,MyAbstractCollection抽象类仿照java.util.AbstractCollection类,均只实现了部分重要的方法,具体请参考源码。其中迭代器用Java.util.Iterator,如果用自定义的迭代器IMyIterator会在foreach循环中报错,提示iterator方法没实现。
package gemme.collection;
import java.util.Iterator;
/**
* 自定义集合Collection
* */
public interface IMyCollection<E> extends Iterable<E> {
// 集合内元素个数
int size();
// 迭代器
@Override
Iterator<E> iterator();
// 添加一个元素
boolean add(E element);
// 删除一个元素
boolean remove(Object o);
// 是否包含该元素
boolean contains(Object o);
}
抽象实现类AbstractCollection继承Collection接口,下面是自定义的抽象类MyAbstractCollection,
package gemme.collection;
import java.util.Iterator;
public abstract class MyAbstractCollection<E> implements IMyCollection<E> {
@Override
public abstract int size();
public abstract Iterator<E> iterator();
@Override
public abstract boolean add(E element);
/**
* 利用迭代器进行删除
* */
@Override
public boolean remove(Object o) {
Iterator<E> it = iterator();
if (o == null) {
while (it.hasNext()) {
if (it.next() == null) {
it.remove();
return true;
}
}
} else {
while (it.hasNext()) {
if (it.next().equals(o)) {
it.remove();
return true;
}
}
}
return false;
}
@Override
public boolean contains(Object o) {
Iterator<E> it = iterator();
if (o == null) {
while (it.hasNext()) {
if (it.next() == null) {
return true;
}
}
} else {
while (it.hasNext()) {
if (it.next().equals(o)) {
return true;
}
}
}
return false;
}
}
接口List、抽象类AbstractList和实现类ArrayList
自定义IMyList接口仿照java.util.List接口,MyArrayList类仿照java.util.ArrayList类,抽象类MyAbstractList仿照java.util.AbstractList。MyAbstractList并没有任何方法或变量,只保留继承关系。
package gemme.collection;
import java.util.Iterator;
public interface IMyList<E> extends IMyCollection<E> {
// 集合内元素个数
@Override
int size();
// 迭代器
@Override
Iterator<E> iterator();
// 添加元素element
@Override
boolean add(E element);
// 在指定位置index,添加元素element
void add(int index, E element);
// 移除元素o
@Override
boolean remove(Object o);
// 移除元素并返回该元素
E remove(int index);
// 集合中是否包含元素o
@Override
boolean contains(Object o);
// 获取指定位置index下的元素
E get(int index);
// 设置指定位置index下的元素为element
E set(int index, E element);
}
package gemme.collection;
/**
* 自定义抽象类AbstractList,保留继承关系,不具体实现
* */
public abstract class MyAbstractList<E> extends MyAbstractCollection<E>
implements IMyList<E> {
}
package gemme.collection;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class MyArrayList<E> extends MyAbstractList<E> implements IMyList<E> {
// 元素数目
private int size;
// 元素存储区间
private Object[] elementData;
// 默认初始数组长度
private static final int DEFAULT_CAPACITY = 10;
public MyArrayList() {
elementData = new Object[DEFAULT_CAPACITY];
size = 0;
}
@Override
public E get(int index) {
rangeCheck(index);
return (E) elementData[index];
}
@Override
public E set(int index, E element) {
rangeCheck(index);
Object oldElement = elementData[index];
elementData[index] = element;
return (E) oldElement;
}
@Override
public int size() {
return size;
}
@Override
public boolean add(E element) {
ensureCapacityInternal(size + 1);
elementData[size++] = element;
return true;
}
@Override
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++;
}
@Override
public E remove(int index) {
rangeCheckForAdd(index);
E oldElement = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0) {
// 从列表中间删除时,元素整体向前移动一位
System.arraycopy(elementData, index + 1, elementData,
index, numMoved);
}
// 释放内存空间便于GC回收
elementData[--size] = null;
return oldElement;
}
private void rangeCheck(int index) {
if (index >= size) {
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
}
private void ensureCapacityInternal(int minCapacity) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
if (minCapacity > elementData.length) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
@Override
public Iterator<E> iterator() {
return new MyItr();
}
/**
* 内部迭代器实现,在源码基础上做了简化,保留下主要功能和逻辑,具体请参考JDK1.7源码
* */
private class MyItr<E> implements Iterator<E> {
int cursor = 0;
int lastRet = -1;
@Override
public boolean hasNext() {
return cursor != size;
}
@Override
public E next() {
int i = cursor;
if (i >= size) {
throw new NoSuchElementException();
}
// Object[] elementArray = elementData;
Object[] elementArray = MyArrayList.this.elementData;
cursor = i + 1;
return (E) elementArray[lastRet = i];
}
@Override
public void remove() {
if (lastRet < 0) {
throw new IllegalStateException();
}
MyArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
}
}
}
验证部分留给观众老爷自己啦,我自测了没有发现bug,大家有什么建议或者发现什么问题请留言啦。