ArrayList集合底层原理封装(CRUD)

  • ArrayList集合底层实质为数组(Object[])
  • 它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要扩容,就要将现有数组的数据复制到新的扩容后的存储空间中。当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制、移动、效率低下。因此,它适合随机查找和遍历,不适合插入和删除。
  • 支持多线程,线程不安全
  • 存储数据有序可重复,即顺序:添加进去的元素 取得元素的顺序一致,重复:两个对象元素一致
  • 支持泛型,指定存储的数据类型(只能传入引用类型包括包装类,不能传入基本数据类型)
package arraybox;
/**
 * @Auther Sunshine
 * @Date 2020/7/2 9:26
 * ArrayList底层原理封装(支持泛型)
 */
public class ArrayBox<T> {
    
    
    //初始化数组
    private Object[] arrayBox;
    //默认初始化数组的容量
    private static final int DEFAULT_CAPACITY =10;
    //有效个数
    private int size=0;
    //默认构造方法带有默认为10的容量的数组容量
    public ArrayBox() {
    
    
        arrayBox=new Object[DEFAULT_CAPACITY];
    }
    //构造方法带有指定容量的数组容量
    public ArrayBox(int Capacity){
    
    
        arrayBox=new Object[Capacity];
    }
    //将ArrayBox集合转换为数组
    public Object[] toArray() {
    
    
        return arrayBox;
    }
    //获取ArrayBox集合中有效元素的个数
    public int Size() {
    
    
        return size;
    }
    //添加元素方法
    public void add(T element){
    
    
        //判断数组容量是否够
        this.ensureCapacity(size+1);
        //将值添加到数组中
        arrayBox[size++]=element;
    }
    //根据索引进行添加元素
    public void add(int index,T element){
    
    
        //判断index索引是否合法
        this.checkAddIndex(index);
        //判断数组容量是否够用
        this.ensureCapacity(size+1);
        if (size==0 || index==size){
    
    
            //如果是第一个添加元素元素或者最后一个添加元素则直接添加
            this.add(element);
        }else {
    
    
            //按照指定位置进行添加元素,先将指定索引位置以后元素向后移动一位
            for (int i = size-1; i >=index ; i--) {
    
    
                arrayBox[i+1]=arrayBox[i];
            }
            //再将指定索引位置进行插入添加
            arrayBox[index]=element;
            //有效个数+1
            size++;
        }
    }
    //获取ArrayBox索引对应的值(取值)
    public T getValue(int index){
    
    
        //判断index索引是否合法
        this.checkIndex(index);
        return (T)arrayBox[index];
    }
    //删除ArrayBox内数组中的某个索引的值
    public T remove(int index){
    
    
        //判断index索引是否合法
        this.checkIndex(index);
        Object oldElementValue=arrayBox[index];
        //删除当前索引位置,将数组往前移值
        this.deleteElement(index);
        return (T)oldElementValue;
    }
    //清空ArrayBox中所有元素
    public void clear(){
    
    
        for (int i = 0; i <size ; i++) {
    
    
            arrayBox[i]=null;
        }
        //有效个数变为0
        size=0;
    }

    //判断ArrayBox集合中是否包含指定元素
    public Boolean contains(Object object){
    
    
        //如果判断返回的索引值大于等于0,则证明包含object,返回true,否则返回false
        return this.indexOf(object)>=0;
    }
    //重写ArrayBox的toString打印方法(StringBuilder拼接)
    @Override
    public String toString() {
    
    
        StringBuilder stringBuilder=new StringBuilder("ArrayBox{");
        for (int i = 0; i <size ; i++) {
    
    
            stringBuilder.append(arrayBox[i]);
            if(i==size-1){
    
    
                break;
            }
            stringBuilder.append(",");
        }
        stringBuilder.append("}");
        return stringBuilder.toString();
    }

    //判断数组容量是否够
    private void ensureCapacity(int minCapacity){
    
    
        if (arrayBox.length-minCapacity<0){
    
    
            //数组容量不够,进行扩容
            this.exchange(minCapacity);
        }
    }
    //数组容量不够,进行扩容
    private void exchange(int minCapacity){
    
    
        //长度按位与运算,扩容1.5倍
        int newLength=arrayBox.length+(arrayBox.length>>1);
        if (newLength-minCapacity<0){
    
    
            //如果扩容1.5倍后还小于最小容量,则用最小容量数作为扩容后的长度
            newLength=minCapacity;
        }
        //数组扩容后,将原数组复制到新数组中
        arrayBox = this.copyArray(arrayBox, newLength);
    }
    //数组扩容后,将原数组复制到新数组中
    private Object[] copyArray(Object[] oldArray,int newLength){
    
    
        //创建一个扩容后长度的新数组
        Object[] newArray=new Object[newLength];
        for (int i = 0; i <oldArray.length ; i++) {
    
    
            //将旧数组中的元素赋值给新数组
            newArray[i]=oldArray[i];
        }
        return newArray;
    }
    //判断index索引是否合法
    private void checkIndex(int index){
    
    
        if (index<0 || index>=size){
    
    
            throw  new ArrayBoxOutOfBoundException("当前size有效元素:"+size+"--你写入的index:"+index);
        }
    }
    //判断添加元素index索引是否合法
    private void checkAddIndex(int index){
    
    
        if (index<0 || index>size){
    
    
            throw  new ArrayBoxOutOfBoundException("当前size有效元素:"+size+"--你写入的添加元素的index:"+index);
        }
    }
    //删除当前索引位置,将数组往前移值
    private void deleteElement(int index){
    
    
        //原数组索引往前赋值
        for (int i = index; i <size-1 ; i++) {
    
    
            arrayBox[i]=arrayBox[i+1];
        }
        //将原数组最后有效个数变为0(末尾元素清空),再将数组有效个数减1------(arrayBox[--size]=0;)
        size-=1;
        arrayBox[size]=null;
    }
    private int indexOf(Object object){
    
    
        //判断传入的值是否为null,再进行遍历查找
        if (object==null){
    
    
            for (int i = 0; i <size ; i++) {
    
    
                if (arrayBox[i]==null){
    
    
                    //查找到则返回索引
                    return i;
                }
            }
        }else {
    
    
            //传入的值不为空,再进行遍历查找
            for (int i = 0; i <size ; i++) {
    
    
                if (object.equals(arrayBox[i])){
    
    
                    //查找到返回索引
                    return i;
                }
            }
        }
        //都没有遍历出则返回-1
        return -1;
    }

}

异常类

package arraybox;

/**
 * @Auther Sunshine
 * @Date 2020/7/2 12:24
 */
//设置数组越界自定义异常类
public class ArrayBoxOutOfBoundException extends RuntimeException{
    
    
    public ArrayBoxOutOfBoundException(String message) {
    
    
        super(message);
    }
    public ArrayBoxOutOfBoundException() {
    
    
    }
}

以上封装只适合for循环遍历,不支持Iterator遍历和增强for循环遍历

猜你喜欢

转载自blog.csdn.net/weixin_45608165/article/details/109757346
今日推荐