Java 中的 ArrayList 可以说是使用频率最高的容器类实现,它实现了java.util.List 接口,实现这个接口的还有一个相对来说使用比较少的LinkedList, 虽然接口相同但是内部的实现还是有很大差异的,具体来说ArrayList正如它的名称所示内部是用数组来实现的,这就决定了ArrayList的随机访问操作非常高效,时间复杂度为O(1), 但是也因为这个原因其随机插入效率很差为O(n), 在末尾插入元素则是例外。具体实现简单来说就是初始化一个数组,随着元素的插入和容量不够或即将不够使进行一次扩容操作,即创建一个新的数组代替原来的数组,并把元素的引用拷贝到新数组中,这里只是一个简单实现作为练习,系统类库的实现要复杂很多功能也更多。
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* @ClassName: MyArrayList
* @Description: 实现简易ArrayList
* @author: he.li
* @service
* @version:V1.0.0
* @param <T>
*
*/
public class MyArrayList1<T> implements Iterable<T> {
//初始容量
private static final int DEFAULT_CAPACITY = 10;
//存储元素的数组
private T[] theItems;
//有效元素数量
private int theSize;
//并发控制计数
private int modCount;
public MyArrayList1() {
doClear();
}
private void doClear() {
theSize = 0;
ensureCapacity(DEFAULT_CAPACITY);
}
//返回当前有效元素数量
public int size() {
return theSize;
}
public boolean isEmpty() {
return theSize == 0;
}
public void add(T val) {
add(theSize, val);
}
//添加元素到末尾,若空间不够则扩容
public void add(int idx, T val) {
if (idx < 0 || idx > theSize) {
throw new IndexOutOfBoundsException();
}
if (theItems.length == theSize) {
ensureCapacity(theSize * 2 + 1);
}
for (int i = theSize - 1; i >= idx; i++) {
theItems[i + 1] = theItems[i];
}
theItems[idx] = val;
theSize++;
}
//删除元素
public T remove(int idx) {
if (idx < 0 || idx >= theSize) {
throw new IndexOutOfBoundsException();
}
T removeItem = theItems[idx];
for (int i = idx + 1; i < theSize; i++) {
theItems[i - 1] = theItems[i];
}
theSize--;
modCount++;
return removeItem;
}
//设置元素
public T set(int idx, T newVal) {
if (idx < 0 || idx >= theSize) {
throw new IndexOutOfBoundsException();
}
T oldVal = theItems[idx];
theItems[idx] = newVal;
modCount++;
return oldVal;
}
//获取元素
public T get(int idx) {
if (idx < 0 || idx >= theSize) {
throw new IndexOutOfBoundsException();
}
return theItems[idx];
}
//扩容
private void ensureCapacity(int newCapacity) {
if (newCapacity < theSize || newCapacity == theItems.length) {
return;
}
@SuppressWarnings("unchecked")
T[] newItems = (T[]) new Object[newCapacity];
for (int i = 0; i < theSize; i++) {
newItems[i] = theItems[i];
}
modCount++;
theItems = newItems;
}
//将当前元素数组缩减至实际元素数量
public void trimToSize() {
ensureCapacity(theSize);
}
@Override
public String toString() {
if (theSize == 0) {
return "[]";
}
StringBuilder sb = new StringBuilder("[");
Iterator<T> it = this.iterator();
for (;;) {
T e = it.next();
sb.append(e == this ? "(this Collection)" : e);
if (!it.hasNext())
return sb.append(']').toString();
sb.append(',').append(' ');
}
}
//获取迭代器
@Override
public Iterator<T> iterator() {
return new MyArrayListIterator();
}
//迭代器内部类
private class MyArrayListIterator implements Iterator<T> {
//当前迭代元素下标
private int current = 0;
private boolean okToMove = false;
private int expectModCount = modCount;
@Override
public boolean hasNext() {
return current < theSize;
}
//获取下一个元素
@Override
public T next() {
//迭代期间若进行了修改操作则抛异常
if (expectModCount != modCount) {
throw new ConcurrentModificationException();
}
//没有元素抛出异常
if (!hasNext()) {
throw new NoSuchElementException();
}
//标记可以删除前一个元素
okToMove = true;
//返回当前元素并且指针向前推进一位
return theItems[current++];
}
public void remove() {
if (expectModCount != modCount) {
throw new ConcurrentModificationException();
}
if (!okToMove) {
throw new IllegalStateException();
}
MyArrayList1.this.remove(--current);
//这里由于remove修改了modCount值因此需要重新赋值,否则后面的操作会抛异常
expectModCount = modCount;
okToMove = false;
}
}
public static void main(String[] args) {
MyArrayList1<String> ma1 = new MyArrayList1<String>();
ma1.add("aa");
ma1.add("bb");
ma1.add("cc");
ma1.add("dd");
ma1.add("ee");
Iterator<String> iterator = ma1.iterator();
while (iterator.hasNext()) {
String next = iterator.next();
System.out.println(next + " removed");
iterator.remove();
}
System.out.println(ma1);
System.out.println(ma1.size());
}
}