ArrayList的编写

ArrayList

构建一个集合,用来存储数据

通过一个集合对象,可以屏蔽掉底层存储的复杂度,实际存储选择使用数组进行。

可以存储任意类型:Java中使用泛型来解决这个问题。

将当前的数组封装到我们的集合对象,ArrayList中去,避免了用户在去调用的过程中还需要去维护数组本身带来的复杂性操作。

编码实现ArrayList构造器
package arraylist;

/**
 * @author renyuhua
 * @date 2021年09月16日 16:33
 * 需求:
 *      1、存储任意类型,我们通过泛型搞定
 *      2、存储数据的大小由用户指定,或者自己指定一个合适的大小。
 */
public class ArrayList<E> {

    /**
     * 实际存储容器的数据
     */
    private E[] elementsDatal;

    /**
     * 指定默认情况下数组的初始长度为10。
     */
    private static final int INIT_CAPACITY = 10;

    /**
     * 空构造器 创建一个指定长度的数组对象。
     */
    public ArrayList(){
        this(INIT_CAPACITY);
    }

    /**
     * 创建一个带参的构造器,创建用户指定长度的数组对象
     * @param capacity 用户指定的数组长度
     */
    public ArrayList(int capacity){
        // 初始化我们对应的存储数据的数据对象即可
        this.elementsDatal = (E[])new Object[capacity];
    }
}

常见查询方法及添加元素
package arraylist;

/**
 * @author renyuhua
 * @date 2021年09月16日 16:33
 * 需求:
 *      1、存储任意类型,我们通过泛型搞定
 *      2、存储数据的大小由用户指定,或者自己指定一个合适的大小。
 */
public class ArrayList<E> {

    /**
     * 实际存储容器的数据
     */
    private E[] elementsDatal;

    /**
     * 指定默认情况下数组的初始长度为10。
     */
    private static final int INIT_CAPACITY = 10;

    /**
     * 维护当前数组中的待添加的索引位置
     * 维护当前数组的元素个数
     */
    private int size;

    /**
     * 空构造器 创建一个指定长度的数组对象。
     */
    public ArrayList(){
        this(INIT_CAPACITY);
    }

    /**
     * 创建一个带参的构造器,创建用户指定长度的数组对象
     * @param capacity 用户指定的数组长度
     */
    public ArrayList(int capacity){
        // 初始化我们对应的存储数据的数据对象即可
        this.elementsDatal = (E[])new Object[capacity];
    }

    /**
     * 添加元素E到当前的集合中
     * @param e
     */
    public void add(E e){
        // 将元素e添加到size指向的索引位置
        elementsDatal[size] = e;
        // 维护一下size即可
        size++;
    }

    /**
     * 查看当前集合是否为空
     * @return
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 查询当前集合中的元素个数
     * @return
     */
    public int getSize(){
        return size;
    }
}

修改添加操作的语义以及重写方法toString
package arraylist;

/**
 * @author renyuhua
 * @date 2021年09月16日 16:33
 * 需求:
 *      1、存储任意类型,我们通过泛型搞定
 *      2、存储数据的大小由用户指定,或者自己指定一个合适的大小。
 */
public class ArrayList<E> {

    /**
     * 实际存储容器的数据
     */
    private E[] elementsDatal;

    /**
     * 指定默认情况下数组的初始长度为10。
     */
    private static final int INIT_CAPACITY = 10;

    /**
     * 维护当前数组中的待添加的索引位置
     * 维护当前数组的元素个数
     */
    private int size;

    /**
     * 空构造器 创建一个指定长度的数组对象。
     */
    public ArrayList(){
        this(INIT_CAPACITY);
    }

    /**
     * 创建一个带参的构造器,创建用户指定长度的数组对象
     * @param capacity 用户指定的数组长度
     */
    public ArrayList(int capacity){
        // 初始化我们对应的存储数据的数据对象即可
        this.elementsDatal = (E[])new Object[capacity];
    }

    /**
     * 添加元素E到当前的集合中的末尾
     * @param e
     */
    public void add(E e){
        addLast(e);
    }

    /**
     * 添加元素到当前集合中的末尾
     * @param e
     */
    public void addLast(E e){
        // 将元素e添加到size指向的索引位置
        elementsDatal[size] = e;
        // 维护一下size即可
        size++;
    }

    /**
     * 查看当前集合是否为空
     * @return
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 查询当前集合中的元素个数
     * @return
     */
    public int getSize(){
        return size;
    }

    public String toString(){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("size:"+size+"{");
        for (int i = 0; i < size; i++) {
            stringBuilder.append(elementsDatal[i]);
            if (i!=size-1){
                stringBuilder.append(",");
            }
        }
        stringBuilder.append("}");
        return stringBuilder.toString();
    }
}

package arraylist;

/**
 * @author renyuhua
 * @date 2021年09月16日 17:05
 */
public class ArrayListTest {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println("打印当前集合是否为空:"+list.isEmpty());
        System.out.println("当前集合中的元素个数:"+list.getSize());

        // 添加元素
        for (int i = 1; i < 11; i++) {
            list.add(i);
            System.out.println("当前集合元素:"+list);
        }
    }
}

添加元素到指定索引位置上
package arraylist;

/**
 * @author renyuhua
 * @date 2021年09月16日 17:05
 */
public class ArrayListTest {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println("当前集合中的元素个数:"+list.getSize());
        list.addFirst(13);
        list.addFirst(12);
        list.addLast(14);
        System.out.println(list);

        for (int i = 0; i < 7; i++) {
            list.add(i);
        }
        System.out.println(list);

    }


    public static void test(){
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println("打印当前集合是否为空:"+list.isEmpty());
        System.out.println("当前集合中的元素个数:"+list.getSize());

        // 添加元素
        for (int i = 1; i < 11; i++) {
            list.add(i);
            System.out.println("当前集合元素:"+list);
        }
    }
}

package arraylist;

/**
 * @author renyuhua
 * @date 2021年09月16日 16:33
 * 需求:
 *      1、存储任意类型,我们通过泛型搞定
 *      2、存储数据的大小由用户指定,或者自己指定一个合适的大小。
 */
public class ArrayList<E> {

    /**
     * 实际存储容器的数据
     */
    private E[] elementsDatal;

    /**
     * 指定默认情况下数组的初始长度为10。
     */
    private static final int INIT_CAPACITY = 10;

    /**
     * 维护当前数组中的待添加的索引位置
     * 维护当前数组的元素个数
     */
    private int size;

    /**
     * 空构造器 创建一个指定长度的数组对象。
     */
    public ArrayList(){
        this(INIT_CAPACITY);
    }

    /**
     * 创建一个带参的构造器,创建用户指定长度的数组对象
     * @param capacity 用户指定的数组长度
     */
    public ArrayList(int capacity){
        // 初始化我们对应的存储数据的数据对象即可
        this.elementsDatal = (E[])new Object[capacity];
    }

    /**
     * 添加元素E到当前的集合中的末尾
     * @param e
     */
    public void add(E e){
        addLast(e);
    }

    /**
     * 添加元素到指定的索引位置上
     * @param e
     * @param index
     */
    public void add(E e,int index){
        // 判定index的合法性,不能添加超过size的元素,防止数组中出现内存碎片
        checkIndex(index);
        // 循环挪动元素
        for (int i = size; i > index; i--)
            elementsDatal[i] = elementsDatal[i-1];
        // 保证index上的元素空出来
        elementsDatal[index] = e;
        // 维护size
        size++;

    }

    /**
     * 添加首元素
     * @param e
     */
    public void addFirst(E e){
        add(e,0);
    }

    /**
     * 判定index的合法性
     * @param index
     */
    private void checkIndex(int index){
        if (index<0 || index>size){
            throw new IllegalArgumentException("index out of bounds index"+index);
        }
    }

    /**
     * 添加元素到当前集合中的末尾
     * @param e
     */
    public void addLast(E e){
        // 将元素e添加到size指向的索引位置
        elementsDatal[size] = e;
        // 维护一下size即可
        size++;
    }

    /**
     * 查看当前集合是否为空
     * @return
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 查询当前集合中的元素个数
     * @return
     */
    public int getSize(){
        return size;
    }

    public String toString(){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("size:"+size+"{");
        for (int i = 0; i < size; i++) {
            stringBuilder.append(elementsDatal[i]);
            if (i!=size-1){
                stringBuilder.append(",");
            }
        }
        stringBuilder.append("}");
        return stringBuilder.toString();
    }
}

扩容操作

数组长度一旦指定了,添加元素过多,导致添加失败

package arraylist;

/**
 * @author renyuhua
 * @date 2021年09月16日 17:05
 */
public class ArrayListTest {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println("当前集合中的元素个数:"+list.getSize());
        list.addFirst(13);
        list.addFirst(12);
        list.addLast(14);
        System.out.println(list);

        for (int i = 0; i < 7; i++) {
            list.add(i);
        }
        list.add(20);
        System.out.println(list);

    }


    public static void test(){
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println("打印当前集合是否为空:"+list.isEmpty());
        System.out.println("当前集合中的元素个数:"+list.getSize());

        // 添加元素
        for (int i = 1; i < 11; i++) {
            list.add(i);
            System.out.println("当前集合元素:"+list);
        }
    }
}

package arraylist;

/**
 * @author renyuhua
 * @date 2021年09月16日 16:33
 * 需求:
 *      1、存储任意类型,我们通过泛型搞定
 *      2、存储数据的大小由用户指定,或者自己指定一个合适的大小。
 */
public class ArrayList<E> {

    /**
     * 实际存储容器的数据
     */
    private E[] elementsDatal;

    /**
     * 指定默认情况下数组的初始长度为10。
     */
    private static final int INIT_CAPACITY = 10;

    /**
     * 维护当前数组中的待添加的索引位置
     * 维护当前数组的元素个数
     */
    private int size;

    /**
     * 维护当前数组中的最大存储容量
     */
    private int capacity;

    /**
     * 空构造器 创建一个指定长度的数组对象。
     */
    public ArrayList(){
        this(INIT_CAPACITY);
    }

    /**
     * 创建一个带参的构造器,创建用户指定长度的数组对象
     * @param capacity 用户指定的数组长度
     */
    public ArrayList(int capacity){
        // 初始化我们对应的存储数据的数据对象即可
        this.elementsDatal = (E[])new Object[capacity];
        this.capacity = capacity;
    }

    /**
     * 添加元素E到当前的集合中的末尾
     * @param e
     */
    public void add(E e){
        addLast(e);
    }

    /**
     * 添加元素到指定的索引位置上
     * @param e
     * @param index
     */
    public void add(E e,int index){
        // 判定index的合法性,不能添加超过size的元素,防止数组中出现内存碎片
        checkIndex(index);

        // 判定当前数组是否满了
        if (size==capacity)
            grow(capacity*2);

        // 循环挪动元素
        for (int i = size; i > index; i--)
            elementsDatal[i] = elementsDatal[i-1];
        // 保证index上的元素空出来
        elementsDatal[index] = e;
        // 维护size
        size++;

    }

    /**
     * 数组扩容的方法
     * @param newCapacity
     */
    private void grow(int newCapacity){
        // 重新定义一个新的数组
        E[] newElementData = (E[]) new Object[newCapacity];
        // 进行数组拷贝
        for (int i = 0; i < size; i++)
            newElementData[i] = elementsDatal[i];
        // 将对象中的elementData重新进行指向
        this.elementsDatal = newElementData;
        // 维护capacity的值
        this.capacity = newCapacity;
    }

    /**
     * 添加首元素
     * @param e
     */
    public void addFirst(E e){
        add(e,0);
    }

    /**
     * 判定index的合法性
     * @param index
     */
    private void checkIndex(int index){
        if (index<0 || index>size){
            throw new IllegalArgumentException("index out of bounds index"+index);
        }
    }

    /**
     * 添加元素到当前集合中的末尾
     * @param e
     */
    public void addLast(E e){
        if (size==capacity)
            grow(capacity*2);
        // 将元素e添加到size指向的索引位置
        elementsDatal[size] = e;
        // 维护一下size即可
        size++;
    }

    /**
     * 查看当前集合是否为空
     * @return
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 查询当前集合中的元素个数
     * @return
     */
    public int getSize(){
        return size;
    }

    @Override
    public String toString(){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("size:"+size+"{");
        for (int i = 0; i < size; i++) {
            stringBuilder.append(elementsDatal[i]);
            if (i!=size-1){
                stringBuilder.append(",");
            }
        }
        stringBuilder.append("} capacity:"+capacity);
        return stringBuilder.toString();
    }
}

删除指定位置上的元素
package arraylist;

/**
 * @author renyuhua
 * @date 2021年09月16日 17:05
 */
public class ArrayListTest {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println("当前集合中的元素个数:"+list.getSize());
        list.addFirst(13);
        list.addFirst(12);
        list.addLast(14);
        System.out.println(list);

        for (int i = 0; i < 7; i++) {
            list.add(i);
        }
        list.add(20);
        System.out.println(list);

        list.remove(0);
        System.out.println(list);

        list.remove(Integer.valueOf(14));
        System.out.println(list);
    }


    public static void test(){
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println("打印当前集合是否为空:"+list.isEmpty());
        System.out.println("当前集合中的元素个数:"+list.getSize());

        // 添加元素
        for (int i = 1; i < 11; i++) {
            list.add(i);
            System.out.println("当前集合元素:"+list);
        }
    }
}

package arraylist;

/**
 * @author renyuhua
 * @date 2021年09月16日 16:33
 * 需求:
 *      1、存储任意类型,我们通过泛型搞定
 *      2、存储数据的大小由用户指定,或者自己指定一个合适的大小。
 */
public class ArrayList<E> {

    /**
     * 实际存储容器的数据
     */
    private E[] elementsDatal;

    /**
     * 指定默认情况下数组的初始长度为10。
     */
    private static final int INIT_CAPACITY = 10;

    /**
     * 维护当前数组中的待添加的索引位置
     * 维护当前数组的元素个数
     */
    private int size;

    /**
     * 维护当前数组中的最大存储容量
     */
    private int capacity;

    /**
     * 空构造器 创建一个指定长度的数组对象。
     */
    public ArrayList(){
        this(INIT_CAPACITY);
    }

    /**
     * 创建一个带参的构造器,创建用户指定长度的数组对象
     * @param capacity 用户指定的数组长度
     */
    public ArrayList(int capacity){
        // 初始化我们对应的存储数据的数据对象即可
        this.elementsDatal = (E[])new Object[capacity];
        this.capacity = capacity;
    }

    /**
     * 添加元素E到当前的集合中的末尾
     * @param e
     */
    public void add(E e){
        addLast(e);
    }

    /**
     * 添加元素到指定的索引位置上
     * @param e
     * @param index
     */
    public void add(E e,int index){
        // 判定index的合法性,不能添加超过size的元素,防止数组中出现内存碎片
        checkIndex(index);

        // 判定当前数组是否满了
        if (size==capacity)
            grow(capacity*2);

        // 循环挪动元素
        for (int i = size; i > index; i--)
            elementsDatal[i] = elementsDatal[i-1];
        // 保证index上的元素空出来
        elementsDatal[index] = e;
        // 维护size
        size++;

    }

    /**
     * 数组扩容的方法
     * @param newCapacity
     */
    private void grow(int newCapacity){
        // 重新定义一个新的数组
        E[] newElementData = (E[]) new Object[newCapacity];
        // 进行数组拷贝
        for (int i = 0; i < size; i++)
            newElementData[i] = elementsDatal[i];
        // 将对象中的elementData重新进行指向
        this.elementsDatal = newElementData;
        // 维护capacity的值
        this.capacity = newCapacity;
    }

    /**
     * 添加首元素
     * @param e
     */
    public void addFirst(E e){
        add(e,0);
    }

    /**
     * 删除指定索引位置上的元素
     * @param index 删除索引
     * @return 删除位置的元素
     */
    public E remove(int index){
        // 判定索引是否有效
        checkIndex(index);
        // 获取待删除的元素
        E ret = elementsDatal[index];
        // 循环挪动元素
        for (int i = index; i < size - 1; i++){
            elementsDatal[i] = elementsDatal[i+1];
        }
        // 维护索引
        size--;
        // 将size指向的元素置为null
        elementsDatal[size] = null;
        return ret;
    }

    /**
     * 删除指定元素
     * @param e
     */
    public void remove(E e){
        // 查找该元素是否存在
        int index = indexOf(e);
        if (index==-1){
            throw new IllegalArgumentException("element e: "+e+" is not found");
        }
        remove(index);
    }

    /**
     * 查找元素是否存在,
     * @param e 元素
     * @return 如果存在,返回对应的索引,如果不存在,返回-1
     */
    public int indexOf(E e){
        // 控制判定用==就可以了,非空值的判定用equals
        if (e==null){
            for (int i = 0; i < size; i++) {
                if (elementsDatal[i]==null){
                    return i;
                }
            }
        }else {
            for (int i = 0; i < size; i++) {
                if (e.equals(elementsDatal[i])){
                    return i;
                }
            }
        }
        return -1;
    }

    /**
     * 判定index的合法性
     * @param index
     */
    private void checkIndex(int index){
        if (index<0 || index>size){
            throw new IllegalArgumentException("index out of bounds index"+index);
        }
    }

    /**
     * 添加元素到当前集合中的末尾
     * @param e
     */
    public void addLast(E e){
        if (size==capacity)
            grow(capacity*2);
        // 将元素e添加到size指向的索引位置
        elementsDatal[size] = e;
        // 维护一下size即可
        size++;
    }

    /**
     * 查看当前集合是否为空
     * @return
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 查询当前集合中的元素个数
     * @return
     */
    public int getSize(){
        return size;
    }

    @Override
    public String toString(){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("size:"+size+"{");
        for (int i = 0; i < size; i++) {
            stringBuilder.append(elementsDatal[i]);
            if (i!=size-1){
                stringBuilder.append(",");
            }
        }
        stringBuilder.append("} capacity:"+capacity);
        return stringBuilder.toString();
    }
}

删除首位元素以及缩容操作
package arraylist;

/**
 * @author renyuhua
 * @date 2021年09月16日 16:33
 * 需求:
 *      1、存储任意类型,我们通过泛型搞定
 *      2、存储数据的大小由用户指定,或者自己指定一个合适的大小。
 */
public class ArrayList<E> {

    /**
     * 实际存储容器的数据
     */
    private E[] elementsDatal;

    /**
     * 指定默认情况下数组的初始长度为10。
     */
    private static final int INIT_CAPACITY = 10;

    /**
     * 维护当前数组中的待添加的索引位置
     * 维护当前数组的元素个数
     */
    private int size;

    /**
     * 维护当前数组中的最大存储容量
     */
    private int capacity;

    /**
     * 空构造器 创建一个指定长度的数组对象。
     */
    public ArrayList(){
        this(INIT_CAPACITY);
    }

    /**
     * 创建一个带参的构造器,创建用户指定长度的数组对象
     * @param capacity 用户指定的数组长度
     */
    public ArrayList(int capacity){
        // 初始化我们对应的存储数据的数据对象即可
        this.elementsDatal = (E[])new Object[capacity];
        this.capacity = capacity;
    }

    /**
     * 添加元素E到当前的集合中的末尾
     * @param e 元素
     */
    public void add(E e){
        addLast(e);
    }

    /**
     * 添加元素到指定的索引位置上
     * @param e 元素
     * @param index 索引
     */
    public void add(E e,int index){
        // 判定index的合法性,不能添加超过size的元素,防止数组中出现内存碎片
        checkIndex(index);

        // 判定当前数组是否满了
        if (size==capacity){
            grow(capacity*2);
        }

        // 循环挪动元素
        for (int i = size; i > index; i--){
            elementsDatal[i] = elementsDatal[i-1];
        }
        // 保证index上的元素空出来
        elementsDatal[index] = e;
        // 维护size
        size++;

    }

    /**
     * 数组扩容的方法
     * @param newCapacity 新的容量
     */
    private void grow(int newCapacity){
        // 重新定义一个新的数组
        E[] newElementData = (E[]) new Object[newCapacity];
        // 进行数组拷贝
        for (int i = 0; i < size; i++)
            newElementData[i] = elementsDatal[i];
        // 将对象中的elementData重新进行指向
        this.elementsDatal = newElementData;
        // 维护capacity的值
        this.capacity = newCapacity;
    }

    /**
     * 添加首元素
     * @param e 元素
     */
    public void addFirst(E e){
        add(e,0);
    }

    /**
     * 删除指定索引位置上的元素
     * @param index 删除索引
     * @return 删除位置的元素
     */
    public E remove(int index){
        // 判定索引是否有效
        checkIndex(index);
        // 获取待删除的元素
        E ret = elementsDatal[index];
        // 循环挪动元素
        for (int i = index; i < size - 1; i++){
            elementsDatal[i] = elementsDatal[i+1];
        }
        // 维护索引
        size--;
        // 将size指向的元素置为null
        elementsDatal[size] = null;
        // 判断是否缩容
        if (size==capacity/2){
            grow(capacity/2);
        }
        return ret;
    }

    /**
     * 删除指定元素
     * @param e 元素
     */
    public void remove(Object e){
        // 查找该元素是否存在
        int index = indexOf((E)e);
        if (index==-1){
            throw new IllegalArgumentException("element e: "+e+" is not found");
        }
        remove(index);
    }

    /**
     * 删除首元素
     * @return 删除位置的元素
     */
    public E removeFirst(){
        return remove(0);
    }

    /**
     * 删除尾元素
     * @return 删除位置的元素
     */
    public E removeLast(){
        E ret = elementsDatal[size-1];
        elementsDatal[size--] = null;
        if (size==capacity/2){
            grow(capacity/2);
        }
        return ret;
    }

    /**
     * 查找元素是否存在,
     * @param e 元素
     * @return 如果存在,返回对应的索引,如果不存在,返回-1
     */
    public int indexOf(E e){
        // 控制判定用==就可以了,非空值的判定用equals
        if (e==null){
            for (int i = 0; i < size; i++) {
                if (elementsDatal[i]==null){
                    return i;
                }
            }
        }else {
            for (int i = 0; i < size; i++) {
                if (e.equals(elementsDatal[i])){
                    return i;
                }
            }
        }
        return -1;
    }

    /**
     * 判定index的合法性
     * @param index 索引
     */
    private void checkIndex(int index){
        if (index<0 || index>size){
            throw new IllegalArgumentException("index out of bounds index"+index);
        }
    }

    /**
     * 添加元素到当前集合中的末尾
     * @param e 元素
     */
    public void addLast(E e){
        if (size==capacity){
            grow(capacity*2);
        }
        // 将元素e添加到size指向的索引位置
        elementsDatal[size] = e;
        // 维护一下size即可
        size++;
    }

    /**
     * 查看当前集合是否为空
     * @return 判断size是否为空
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 查询当前集合中的元素个数
     * @return 返回size
     */
    public int getSize(){
        return size;
    }

    @Override
    public String toString(){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("size:"+size+"{");
        for (int i = 0; i < size; i++) {
            stringBuilder.append(elementsDatal[i]);
            if (i!=size-1){
                stringBuilder.append(",");
            }
        }
        stringBuilder.append("} capacity:"+capacity);
        return stringBuilder.toString();
    }
}

package arraylist;

/**
 * @author renyuhua
 * @date 2021年09月16日 17:05
 */
public class ArrayListTest {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println("当前集合中的元素个数:"+list.getSize());
        list.addFirst(13);
        list.addFirst(12);
        list.addLast(14);
        System.out.println(list);

        for (int i = 0; i < 7; i++) {
            list.add(i);
        }
        list.add(20);
        System.out.println(list);
        System.out.println(list.removeLast());
        System.out.println(list);
        System.out.println(list.removeFirst());
        System.out.println(list);
    }


    public static void test(){
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println("打印当前集合是否为空:"+list.isEmpty());
        System.out.println("当前集合中的元素个数:"+list.getSize());

        // 添加元素
        for (int i = 1; i < 11; i++) {
            list.add(i);
            System.out.println("当前集合元素:"+list);
        }
    }
}

关于复杂度震荡问题及边界检查
package arraylist;

/**
 * @author renyuhua
 * @date 2021年09月16日 17:05
 */
public class ArrayListTest {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>(2);
        System.out.println(list);
        for (int i = 0; i < 2; i++){
            list.add("apple"+i);
        }
        for (int i = 2; i < 12; i++) {
            if (i%2==0){
                list.addLast("apple2");
            }
            else {
                list.removeLast();
            }
            System.out.println(list);

        }
        list.remove("apple1");
        list.remove("apple0");
        System.out.println(list);
        list.add("banana");
        System.out.println(list);
        list.removeFirst();
        System.out.println(list);
        list.add("banana");
        System.out.println(list);
    }

    public static void test2(){
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println("当前集合中的元素个数:"+list.getSize());
        list.addFirst(13);
        list.addFirst(12);
        list.addLast(14);
        System.out.println(list);

        for (int i = 0; i < 7; i++) {
            list.add(i);
        }
        list.add(20);
        System.out.println(list);
        System.out.println(list.removeLast());
        System.out.println(list);
        System.out.println(list.removeFirst());
        System.out.println(list);
    }

    public static void test(){
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println("打印当前集合是否为空:"+list.isEmpty());
        System.out.println("当前集合中的元素个数:"+list.getSize());

        // 添加元素
        for (int i = 1; i < 11; i++) {
            list.add(i);
            System.out.println("当前集合元素:"+list);
        }
    }
}

package arraylist;

/**
 * @author renyuhua
 * @date 2021年09月16日 16:33
 * 需求:
 *      1、存储任意类型,我们通过泛型搞定
 *      2、存储数据的大小由用户指定,或者自己指定一个合适的大小。
 */
public class ArrayList<E> {

    /**
     * 实际存储容器的数据
     */
    private E[] elementsDatal;

    /**
     * 指定默认情况下数组的初始长度为10。
     */
    private static final int INIT_CAPACITY = 10;

    /**
     * 维护当前数组中的待添加的索引位置
     * 维护当前数组的元素个数
     */
    private int size;

    /**
     * 维护当前数组中的最大存储容量
     */
    private int capacity;

    /**
     * 空构造器 创建一个指定长度的数组对象。
     */
    public ArrayList(){
        this(INIT_CAPACITY);
    }

    /**
     * 创建一个带参的构造器,创建用户指定长度的数组对象
     * @param capacity 用户指定的数组长度
     */
    public ArrayList(int capacity){
        // 初始化我们对应的存储数据的数据对象即可
        this.elementsDatal = (E[])new Object[capacity];
        this.capacity = capacity;
    }

    /**
     * 添加元素E到当前的集合中的末尾
     * @param e 元素
     */
    public void add(E e){
        addLast(e);
    }

    /**
     * 添加元素到指定的索引位置上
     * @param e 元素
     * @param index 索引
     */
    public void add(E e,int index){
        // 判定index的合法性,不能添加超过size的元素,防止数组中出现内存碎片
        checkIndex(index);

        // 判定当前数组是否满了
        if (size==capacity){
            grow(capacity*2);
        }

        // 循环挪动元素
        for (int i = size; i > index; i--){
            elementsDatal[i] = elementsDatal[i-1];
        }
        // 保证index上的元素空出来
        elementsDatal[index] = e;
        // 维护size
        size++;

    }

    /**
     * 数组扩容的方法
     * @param newCapacity 新的容量
     */
    private void grow(int newCapacity){
        // 重新定义一个新的数组
        E[] newElementData = (E[]) new Object[newCapacity];
        // 进行数组拷贝
        for (int i = 0; i < size; i++)
            newElementData[i] = elementsDatal[i];
        // 将对象中的elementData重新进行指向
        this.elementsDatal = newElementData;
        // 维护capacity的值
        this.capacity = newCapacity;
    }

    /**
     * 添加首元素
     * @param e 元素
     */
    public void addFirst(E e){
        add(e,0);
    }

    /**
     * 删除指定索引位置上的元素
     * @param index 删除索引
     * @return 删除位置的元素
     */
    public E remove(int index){
        // 判定索引是否有效
        checkIndex(index);
        // 获取待删除的元素
        E ret = elementsDatal[index];
        // 循环挪动元素
        for (int i = index; i < size - 1; i++){
            elementsDatal[i] = elementsDatal[i+1];
        }
        // 维护索引
        size--;
        // 将size指向的元素置为null
        elementsDatal[size] = null;
        // 判断是否缩容
        if (size==capacity/4&&capacity/2!=0){
            grow(capacity/2);
        }
        return ret;
    }

    /**
     * 删除指定元素
     * @param e 元素
     */
    public void remove(Object e){
        // 查找该元素是否存在
        int index = indexOf((E)e);
        if (index==-1){
            throw new IllegalArgumentException("element e: "+e+" is not found");
        }
        remove(index);
    }

    /**
     * 删除首元素
     * @return 删除位置的元素
     */
    public E removeFirst(){
        return remove(0);
    }

    /**
     * 删除尾元素
     * @return 删除位置的元素
     */
    public E removeLast(){
//        E ret = elementsDatal[size-1];
//        elementsDatal[size--] = null;
//        if (size==capacity/2){
//            grow(capacity/2);
//        }
//        return ret;
        return remove(size-1);
    }

    /**
     * 查找元素是否存在,
     * @param e 元素
     * @return 如果存在,返回对应的索引,如果不存在,返回-1
     */
    public int indexOf(E e){
        // 控制判定用==就可以了,非空值的判定用equals
        if (e==null){
            for (int i = 0; i < size; i++) {
                if (elementsDatal[i]==null){
                    return i;
                }
            }
        }else {
            for (int i = 0; i < size; i++) {
                if (e.equals(elementsDatal[i])){
                    return i;
                }
            }
        }
        return -1;
    }

    /**
     * 判定index的合法性
     * @param index 索引
     */
    private void checkIndex(int index){
        if (index<0 || index>size){
            throw new IllegalArgumentException("index out of bounds index"+index);
        }
    }

    /**
     * 添加元素到当前集合中的末尾
     * @param e 元素
     */
    public void addLast(E e){
        if (size==capacity){
            grow(capacity*2);
        }
        // 将元素e添加到size指向的索引位置
        elementsDatal[size] = e;
        // 维护一下size即可
        size++;
    }

    /**
     * 查看当前集合是否为空
     * @return 判断size是否为空
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 查询当前集合中的元素个数
     * @return 返回size
     */
    public int getSize(){
        return size;
    }

    @Override
    public String toString(){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("size:"+size+"{");
        for (int i = 0; i < size; i++) {
            stringBuilder.append(elementsDatal[i]);
            if (i!=size-1){
                stringBuilder.append(",");
            }
        }
        stringBuilder.append("} capacity:"+capacity);
        return stringBuilder.toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值