通过实现Iterator接口,可以通过泛型实现一个ArrayList。下面给出源码,上面带有详细的注释。
这里面有个内部类,通过iterator()方法返回这个内部类的实例,实现类似迭代器的功能,从而可以用增强的for循环。
package List;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* ArrayList的泛型实现
* @author 熊义杰
* @date 2019/5/22
* @param <AnyType>
*/
public class MyArrayList<AnyType> implements Iterable<AnyType>{
/**
* 默认扩容值
*/
private static final int DEFAULT_CAPATITY = 10;
/**
* 数组大小
*/
private int theSize;
/**
* 存储列表的数组
*/
private AnyType[] theItems;
public MyArrayList(){
doClear();
}
/**
* 初始化当前大小和list容量
*/
private void doClear() {
theSize = 0;
ensureCapatity(DEFAULT_CAPATITY);
}
/**
* 返回数组实际使用的大小
* @return
*/
public int size(){
return theSize;
}
public boolean isEmpty(){
return size() == 0;
}
/*
* 将当前数组大小传进去,通过扩容方法,去掉数组中预留的空间
* (因为每次申请空间,都会多申请0.5倍的空间)
*/
public void trimToSize(){
ensureCapatity(size());
}
public AnyType get(int index){
//数组下标是从0开始,到size-1
if(index < 0 || index >= size()){
//抛出数组下标越界的异常
throw new ArrayIndexOutOfBoundsException();
}
return theItems[index];
}
public AnyType set(int index,AnyType newVal){
if(index < 0 || index >= size()){
throw new ArrayIndexOutOfBoundsException();
}
AnyType old = theItems[index];
theItems[index] = newVal;
//返回旧值
return old;
}
/**
* 将list数组进行扩容,变为原来的两倍+1
* @param newCapatity
*/
private void ensureCapatity(int newCapatity) {
//如果新增容量小于当前大小,就忽略
if(newCapatity < theSize)
return;
//把旧值复制到一个数据中
AnyType[] old = theItems;
/*因为不能直接创建泛型数组,这里先创建一个泛型类型界限的数组,
* 然后使用一个泛型数组进行类型转换,得到泛型数组
* 这里会报一个警告,但这是不能避免的,可以忽略
*/
theItems = (AnyType[]) new Object[newCapatity];
for(int i = 0;i < size(); i++){
//将旧值复制新创建的数组中,完成扩容
theItems[i] = old[i];
}
}
/**
* 在数据尾部增加一个值
* @param data
* @return
*/
public boolean add(AnyType data){
add(size(),data);
return true;
}
/**
* 在任意位置增加一个元素
* 由于每次增加都要移动大量的元素
* 导致花费的时间是昂贵的
* @param index
* @param data
*/
private void add(int index, AnyType data) {
//如果实际大小等于数组容量,就进行两倍的扩容
if(theItems.length == size()){
ensureCapatity(size() * 2 + 1);
}
for(int i = size();i > index;i --){
//数组元素从指定index位置右移一位
theItems[i] = theItems[i - 1];
}
theItems[index] = data;
//数组大小+1
theSize ++;
}
/**
* 在任意一个位置删除一个元素
* @param index
* @return
*/
public AnyType remove(int index){
AnyType removeItem = theItems[index];
for(int i = index;i < size() - 1;i ++){
//数组元素从指定index位置左移一位
theItems[i] = theItems[i + 1];
}
theSize --;
//返回删除的元素
return removeItem;
}
/**
* Iterator接口
*/
@Override
public Iterator<AnyType> iterator() {
return new ArrayListIterator();
}
/**
* 一个内部类,实现Iterator
* @author 熊义杰
* @date 2019/5/22
*/
private class ArrayListIterator implements Iterator<AnyType>{
//初始化当前位置为0
private int current = 0;
/**
* 判断下一个元素是否存在
* 就是判断当前位置值是否小于数组实际大小
* @return
*/
public boolean hasNext(){
return current < size();
}
/**
* 获取当前元素
* @return
*/
public AnyType next(){
//如果下一个元素不存在,就抛出异常
if(!hasNext()){
throw new NoSuchElementException();
}
//返回当前元素,并将当前位置后移一位
return theItems[current++];
}
public void remove(){
//调用顶级类的remove方法
MyArrayList.this.remove(current -- );
}
}
}
写一个主类来测试自己写的ArrayList是否有效。
package List;
import java.util.Iterator;
/**
* 主方法,测试实现的list类
* @author 熊义杰
* @date 2019/5/22
*/
public class Main {
public static void main(String[] args){
MyArrayList<Integer> list = new MyArrayList<>();
for(int i=0;i<20;i++){
list.add(i);
}
//调用list实现的iterator接口
Iterator<Integer> it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
System.out.println("size = " + list.size());
}
}
测试结果: