ArrayList源码简述

前言

开发一个springboot项目,其本质便是对数据库的各种操作,所以在系统开发过程中,学会如何对数据库的增删改查(CRUD)十分重要,那么其中哪个操作用的是最多的呢?毫无疑问,查询操作是最多的(如:分页查询,修改时原数据在页面的回显等),那么查询时用的最多的便是ArrayList集合,接下来将仿照ArrayList源码写一个MyArrayList类,带大家简单了解一下ArrayList的源码。

一、MyArrayList类的组成

一个类的包含有属性,构造方法(无参构造方法和有参构造方法),方法等,那么MyArrayList类首先要继承ArrayList类,然后重写父类的构造方法和ArrayList提供的各种方法(注:不需要重写父类所有方法)

二、构造方法重写

1.ArrayList定义

首先先来看下顶级接口Collection的方法:

  public interface Collection<E> extends Iterable<E> {
      int size();
      boolean isEmpty();
      boolean contains(Object o);
      Iterator<E> iterator();
      Object[] toArray();
      <T> T[] toArray(T[] a);
      boolean add(E e);
      boolean remove(Object o);
     boolean containsAll(Collection<?> c);
     boolean addAll(Collection<? extends E> c);
     boolean removeAll(Collection<?> c);
     boolean retainAll(Collection<?> c);
     void clear();
     boolean equals(Object o);
     int hashCode();
}

然后是接口List的定义:

 public interface List<E> extends Collection<E> {
           int size();
           boolean isEmpty();
          boolean contains(Object o);
           Iterator<E> iterator();
           Object[] toArray();
           <T> T[] toArray(T[] a);
           boolean add(E e);
           boolean remove(Object o);
          boolean containsAll(Collection<?> c);
          boolean addAll(Collection<? extends E> c);
          boolean addAll( int index, Collection<? extends E> c);
          boolean removeAll(Collection<?> c);
          boolean retainAll(Collection<?> c);
          void clear();
          boolean equals(Object o);
          int hashCode();
          E get( int index);
          E set( int index, E element);
          void add( int index, E element);
          E remove( int index);
          int indexOf(Object o);
          int lastIndexOf(Object o);
          ListIterator<E> listIterator();
          ListIterator<E> listIterator( int index);
          List<E> subList( int fromIndex, int toIndex);
}

再看下ArrayList的定义:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

可以看出ArrayList继承AbstractList(这是一个抽象类,对一些基础的list操作进行封装),实现List,RandomAccess,Cloneable,Serializable几个接口。RandomAccess接口的主要作用是标识一个类是否支持随机访问。‌Cloneable接口的主要作用是作为一个标记,表明实现了该接口的类支持对象的克隆操作。Serializable接口的主要作用是标识一个类是否可以序列化。

2.MyArrayList定义

模仿ArrayList的定义,写MyArrayList定义:

public class MyArrayList<E> extends AbstractList<E>  implements 
        List<E>, RandomAccess, Cloneable, java.io.Serializable

3.MyArrayList无参构造和有参构造

//属性:
//数组
private Object[] elementData;
//数组大小
private int size;
//有参构造:
//构造一个具有指定容量的list
public MyArrayList(int index){
        super();
        //如果输入的容量小于0,则会抛出异常
        if (index < 0){
            throw new IllegalArgumentException( "索引输入不合法: " + index);
        }
        //底层用的是数组保存数据
        this.elementData = new Object[index];

    }
//无参构造:
public MyArrayList(){
//构造一个容量为10的list
        this(10);
    }

3.MyArrayList的方法

下面写几个常用的方法:
1.add(int index, E e)方法:在指定位置插入一个元素

public void add(int index, E e) {
        //如果输入的位置索引大于数组长度或者小于0,则抛出异常
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException("输入不合法");
        //用ensureCapacity(int minCapacity)方法进行数组容量检查
        ensureCapacity( size+1);
        /*
        用System.arraycopy进行数组拷贝
        System.arraycopy第一个参数:从A数组拷贝
        第二个参数:从哪个索引开始拷贝
        第三个参数:拷贝到B数组
        第四个参数:拷贝的数据从B哪个索引开始存放
        第五个参数:拷贝几个数据
        */
        System.arraycopy(e, index, e, index + 1, size - index);
        elementData[index] = e;
        //数组容量++
        size++;
    }
    

//数组容量检查,不够时则进行扩容
    public void ensureCapacity( int minCapacity) {
        modCount++;
        // 当前数组的长度
        int oldCapacity = elementData .length;
        // 最小需要的容量大于当前数组的长度则进行扩容
        if (minCapacity > oldCapacity) {
            Object oldData[] = elementData;
            // 新扩容的数组长度为旧容量的1.5倍+1
            int newCapacity = (oldCapacity * 3)/2 + 1;
            // 如果新扩容的数组长度还是比最小需要的容量小,则以最小需要的容量为长度进行扩容
            if (newCapacity < minCapacity)
                newCapacity = minCapacity;
            //用Arrays.copyOf进行数据拷贝
            elementData = Arrays.copyOf( elementData, newCapacity);
        }
    }

2.add(E e)方法:就是将数据添加到数组的末尾

3.remove(int index)方法:删除指定索引的元素

    //根据索引位置删除元素
    public E remove(int index){
        // 数组越界检查
        RangeCheck(index);
        modCount++;
        //去除要删除的元素,供返回使用
        E oldValue = (E) elementData[index];
        //计算出要拷贝的数量
        int num = size - index - 1;
        //拷贝数组
        System.arraycopy(elementData, index+1, elementData, index, num);
        //将数组最后一个元素置空,好让gc回收
        //数组长度-1
        elementData[--size] = null;
        //返回删除的元素
        return oldValue;
    }

    //数组越界检查
    public void RangeCheck(int index) {
        if (index >= size )
            throw new IndexOutOfBoundsException("索引越界");
    }

}

4.set(int index, E element):修改指定索引元素

//修改指定索引元素
    public E set(int index, E e) {
        //数组越界检查
        RangeCheck(index);
        //获取修改的元素,供返回使用
        E oldValue = (E) elementData[index];
        //修改元素为新元素
        elementData[index] = e;
        //返回修改的元素
        return oldValue;
    }

5.get(int index):获取指定索引的元素

//查询指定索引元素
    public E get(int index) {
        //数组越界检查
        RangeCheck(index);

        return (E) elementData[index];

    }

6.isEmpty():判断list是否为空

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

7.indexOf(Object o):返回此list中首次出现的指定元素的索引,或如果此list不包含元素,则返回 -1

public int indexOf(Object o) {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
        return -1;
    }

8.lastIndexOf(Object o) :返回此list中最后一次出现的指定元素的索引,或如果此list不包含索引,则返回 -1。

public int lastIndexOf(Object o) {
        for (int i = size - 1; i >= 0; i--)
            if (o.equals(elementData[i]))
                return i;
        return -1;
    }

总结

方法有很多,这里只写了部分常用的方法,其他方法可以看ArrayList源码比葫芦画瓢。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值