手写一个ArrayList

    xiaoxiao2022-07-14  168

    通过实现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()); } }

    测试结果:

    最新回复(0)