ArrayList实现
本文给出ArrayList的简单实现,ArrayList内部采用数组实现,因此具有较快的元素访问速度,但同时不利于元素的插入和删除,如当在最前端插入元素,会导致所有其余所有元素后移一位,造成N次迭代,复杂度O(N)。实现其简单的增删改查,提供自动扩充功能,并内置迭代器,可以进行增广遍历。
功能描述
- 提供易于使用的ArrayList泛型实现,避免与类库冲突,命名为MyArrayList,其包含的主要细节如下:
- MyArrayList保持基础数组,数组的容量,以及存储在MyArrayList中当前的项数;
- MyArrayList设计一种机制用来改变数组容量,通过获得一个新数组,将老数组的内容复制到新数组,允许JVM回收老数组;
- MyArrayList提供set和get的实现;
- MyArrayList提供基本的例程。如size(), clear(), isEmpty()等典型的单行程序;同时提供remove和两个版本的add,一个在任意位置添加,一个在集合末端添加,并且数组容量不足,add方法将扩充数组;
- MyArrayList提供一个实现Iterator接口的类,该类存储迭代序列中的下一个下标,并提供next, hasNext, remove方法实现。MyArrayList的迭代器方法直接返回实现Iterator接口的该类的一个新的实例,代码中采用两种方式,私有内部类和嵌套类实现迭代器。
代码实现
package com.yam.base;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* ArrayList的实现
* @author: Ympery
* @date: 2017/3/8 11:10.
*/
public class MyArrayList<AnyType> implements Iterable<AnyType> {
/**
* 默认大小
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 集合大小
*/
private int theSize;
/**
* 类型数组
*/
private AnyType[] theItems;
public MyArrayList() { clear(); }
/**
* 清理集合
*/
public void clear() {
theSize = 0;
ensureCapacity(DEFAULT_CAPACITY);
}
/**
* 返回集合容量
* @return 大小
*/
public int size() { return theSize; }
/**
* 判断是否为空
* @return
*/
public boolean isEmpty() { return 0 == size(); }
/**
* 将集合缩减到内容大小
*/
public void trimToSize() { ensureCapacity(size()); }
/**
* 获取集合元素
* @param idx 位置
* @return
*/
public AnyType get(int idx) {
if (0 > idx || idx >= size())
throw new ArrayIndexOutOfBoundsException();
return theItems[idx];
}
/**
* 根据元素位置设置该元素值
* @param idx 位置
* @param newVal 要设置的值
* @return 该元素原有的值
*/
public AnyType set(int idx, AnyType newVal) {
if (0 > idx || idx >= size())
throw new ArrayIndexOutOfBoundsException();
AnyType old = theItems[idx];
theItems[idx] = newVal;
return old;
}
/**
* 列表copy,容量的扩张和收缩
* @param newCapacity
*/
public void ensureCapacity(int newCapacity) {
if (newCapacity < theSize)
return;
AnyType[] old = theItems;
// 因为泛型数组的创建时非法的,因此创建一个有界数组,强制转换
theItems = (AnyType[]) new Object[newCapacity];
for (int i = 0; i < size(); i++)
theItems[i] = old[i];
}
/**
* 在list的末端插入x
* @param x
* @return
*/
public boolean add(AnyType x) {
add(size(), x);
return true;
}
/**
* 向集合中插入元素(任意位置)
* @param idx
* @param x
*/
public void add(int idx, AnyType x) {
/**
* 判断当前元素个数,是否需要扩充集合大小
*/
if (theItems.length == size())
ensureCapacity(size() * 2 + 1);
for (int i = theSize; i > idx; i--)
theItems[i] = theItems[i - 1];
theItems[idx] = x;
theSize++;
}
/**
* 删除指定位置元素
* @param idx
* @return
*/
public AnyType remove(int idx) {
AnyType removedItem = theItems[idx];
for (int i = idx; i < size(); i++)
theItems[i] = theItems[i++];
theSize--;
return removedItem;
}
/**
* 获取一个当前集合的迭代器
* @return
*/
/*public Iterator<AnyType> iterator() {
return new ArrayListIterator();
}*/
/**
* 内部类构造集合迭代器
*/
/*private class ArrayListIterator implements Iterator<AnyType>{
*//**
* 记录当前遍历位置
*//*
private int current = 0;
*/
/**
* 是否由下一个元素
*
* @return
*//*
@Override
public boolean hasNext() {
return current < theSize;
}
@Override
public AnyType next() {
if (!hasNext())
throw new NoSuchElementException();
return theItems[current++];
}
@Override
public void remove() {
MyArrayList.this.remove(--current);
}
}*/
/**
* 这里在获取迭代器必须传入该集合本身
* @return
*/
public ArrayListIterator<AnyType> iterator() {
return new ArrayListIterator<>(this);
}
/**
* 使用嵌套类构造集合迭代器
* @param <AnyType>
*/
private static class ArrayListIterator<AnyType> implements Iterator<AnyType> {
/*
* 当前位置
*/
private int current = 0;
private MyArrayList<AnyType> theList;
public ArrayListIterator(MyArrayList list){
theList = list;
}
@Override
public boolean hasNext() {
return current < theList.size();
}
@Override
public AnyType next() {
if (!hasNext())
throw new NoSuchElementException();
return theList.theItems[current++];
}
@Override
public void remove() {
theList.remove(--current);
}
}
/**
* 测试
* @param args
*/
public static void main(String[] args) {
MyArrayList<Character> strList = new MyArrayList<>();
char c = 'a';
for (int i = 0; i < 15; i++)
strList.add(c++);
for(char ch : strList)
System.out.print(ch + " ");
System.out.println("删除之前:" + strList.size());
strList.remove(5);
for(char ch : strList)
System.out.print(ch + " ");
System.out.println("删除之后:" + strList.size());
}
}
注:代码中的注释部分是采用内部类迭代器实现,文章最后采用了嵌套类实现(我习惯吧静态内部类称作嵌套类),两者区别这里不做赘述。