使用数组实现ArrayList实践

版权声明: https://blog.csdn.net/u011286584/article/details/82805177

使用数组的方式实现一个 ArrayList 泛型类,为避免与类型库中的类混淆,这里将类命名为 MyArrayList
定期整理点滴,完善自己,今后给洋哥挣钱,陪伴着让我的小宝贝发自内心爱上笑,加油吧

这里写图片描述

import java.util.Iterator;
import java.util.NoSuchElementException;

public class MyArrayList<AnyType> implements Iterable<AnyType> {
    
    private static final int DEFAULT_CAPACITY = 10;

    private int theSize;
    private AnyType[] theItems;

    public MyArrayList() {
        doClear();
    }

    public void clear() {
        doClear();
    }

    private void doClear() {
        theSize = 0;
        ensuerCapacity(DEFAULT_CAPACITY);
    }

    public int size() {
        return theSize;
    }

    public boolean isEmpty() {
        return size() == 0;
    }

    public void trimToSize() {
        ensureCapacity(size());
    }

    public AnyType get(int idx) {
        if (idx < 0 || idx >= size()) {
            throw new ArrayIndexOutOfBoundsException();
        }
        return theItems[idx];
    }

    public AnyType set(int idx, Anytype newValue) {
        if (idx < 0 || idx >= size()) {
            throw new ArrayIndexOutOfBoundsException();
        }
        AnyType old = theItems[idx];
        theItems[idx] = newValue;
        return old;
    }

    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];
        }
    }

    public boolean add(AnyType value) {
        add(size(), value);
        return true;
    }

    public void add(int idx, AnyType value) {
        if (theItem.length == size()) {
            ensureCapacity(size() * 2 + 1);
        }
        for (int i = theSize; i > idx; i--) {
            theItems[i] = theItems[i - 1];
        }
        theItems[idx] = value;
        theSize++;
    }

    public AnyType remove(int idx) {
        AnyType removeItem= theItems[idx];
        for (int i = idx; i < size() - 1; i++) {
            theItems[i] = theItems[i + 1];
        }
        theSize--;
        return removeItem;
    }

    public Iterator<AnyType> iterator() {
        return new ArrayListIterator();
    }

    private class ArrayListIterator implements Iterator<AnyType> {
        private int current = 0;
        public boolean hasNext() {
            return current < size();
        }
        public AnyType next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            return theItems[current++];
        }
        public void remove() {
            MyArrayList.this.remove(--current);
        }
    }
}

初始声明 theSize 与 theItmes 作为数据成员存储 MyArrayList 大小及数组变量
第 15 行到第 34 行是一个短历程,实现了 clear、size、trimToSize、isEmpty 方法
第 11 行到第 13 行是类的构造方法,执行 doClear() 将 List 长度置为 0 并改写内部存储数组的长度为默认值,
第 36 行到第 50 行 实现 get 与 set 方法
第 52 行到第 62 行实现了ensureCapacity() 改变数组容量的方法,即通过获取一个新数组将原数组中的内容拷贝到新数组中改变容量
第 57 行存储对原始数组的一个引用, 第 58 行为新数组分配内存, 第 59 行到第 61 行将原数组中的内容拷贝到新数组中,因创建泛型数组非法,第 58 行创建了一个泛型类型限界数组,使用一个数组进行类型转换,这会产生一个编译器警告,但在泛型集合的实现中不可避免。
第 64 行到第 78 行实现了两个 add 方法,尽管两个方法名相同,但参数有所不同,这涉及到方法重载,要求方法的参数类型和顺序不同,返回值不做要求,这里两个方法的参数列表不同,满足方法重载的条件,第一个是添加到 List 末端并调用一个添加到指定位置的一般版本来实现,这种方式计算昂贵,因为它需要移动在指定位置上或指定位置后面的那些元素到一个更高的位置上,应该注意,使用方法可能增加容量,扩容代价同样昂贵,所以如果要扩容,它要变成原来的两倍以避免不得不再次扩容,其中 +1 是大小为 0 的情况
第 80 行到第 87 行实现 remove 方法类似添加
第 74 行于第 83 行的代码很简洁,也有技巧,首先第 74 行,变量 i 赋值为 theSize,则 theSize[i] 代表扩容后最后一个元素,而 theSize[i - 1] 带表原数组最后一个元素,赋值语句实现指定位置后的每个元素向后移一位操作,同样,第 83 行赋值语句,实现指定位置后的每个元素向前移一位操作
最后处理 iterator 方法和相关迭代器实现,iterator 直接返回 ArrayListIterator 类的一个实例,这里 ArrayListIterator 使用了一个复杂结构,叫做内部类,该类实现了 Iterator 一个接口,current 存储当前的位置,提供 hasNext、next、remove 方法实现,当前位置表示要被查看的下一元素数组索引。
2018.09.21 于广州

猜你喜欢

转载自blog.csdn.net/u011286584/article/details/82805177
今日推荐