其他分享
首页 > 其他分享> > 手写ArrayList实现基本功能

手写ArrayList实现基本功能

作者:互联网

手写ArrayList实现基本功能

文章目录

概述

List是一种线性的列表结构,继承自Collection接口,是一种有序集合。

ArrayList是用数组来实现的List

直接看源码可得

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

AbstractList:大部分List集合的共同父类,提供了一些基本的方法和封装,以及通用的一些Api

List:列表标准接口,列表是一个有序集合,又被称为序列,该接口对内部的每一个元素的插入位置都有精确控制

RandomAccess:一个标记性质的随机访问接口,没有提供任何方法,如果一个类实现这个接口,表示这个类用索引比迭代器更快

Cloneable:标记可克隆对象 ,没有实现该接口的对象在调用Object.clone()方法时会抛出异常 分为浅拷贝和深拷贝 这里默认都是浅拷贝

java.io.Serializable:序列化标记接口 被此接口标记的类 可以实现Java序列化和反序列化

手写内容

构造器

	/**
     * 指定数组初始容量
     * @param initialCapacity
     */
    public MyArrayList(int initialCapacity){
        if(initialCapacity < 0){
            throw new IllegalArgumentException("初始容量不能小于0");
        }
        elementData = new Object[initialCapacity];
    }

    /**
     * 默认初始化容量为10
     */
    public MyArrayList(){
        this(DEFAULT_CAPACITY);
    }

成员变量和常量

elementData是一个对象数组 用来存储数据的

DEFAULT_CAPACITY则是和ArrayList的默认大小一样为10

size则是实际ArrayList的大小

 /**
     * 定义默认的数组容量
     */
    private final static int DEFAULT_CAPACITY = 10;
    /**
     * 底层采用数组存放数据
     */
    private Object[] elementData;

    /**
     * 实际ArrayList的大小
     */
    private int size;

添加-add方法

 public void add(Object object){
        //判断实际存放的数据容量是否大于elementData容量
        ensureExplicitCapacity(size + 1);
        elementData[size++] = object;
    }
public void add(int index, Object object){
        //判断实际存放的数据容量是否大于elementData容量
        ensureExplicitCapacity(size + 1);
		//数组拷贝
        System.arraycopy(elementData, index,elementData, index + 1, size - index);
        elementData[index] = object;
        size ++;
    }

扩容-ensureExplicitCapacity(size + 1);

if(newCapacity - minCapacity < 0){
        newCapacity = minCapacity;
}
        是为了保证最小容量要和minCapacity 相同
        假使自定义时的容量为1  +1以后变成2   但是经过位运算以后 1  +   1>>1 为1.5还是1 扩容事实上是失败的
        出现java.lang.ArrayIndexOutOfBoundsException异常  而加个if判断和赋值   保证一个最小容量
        也就是 初始为1 时  1+ 1传入后  minCapacity = 2
        此时判断为负 执行newCapacity = minCapacity  
        这是新数组的长度就为2  就可以正常插入数据
/**
     * 扩容
     * @param minCapacity 最小的扩容量 当前的size + 1
     */
    private void ensureExplicitCapacity(int minCapacity){
        if(size == elementData.length){
//            int newCapacity = 2 * size;
            //源码中的扩容
            int  oldCapacity = elementData.length;
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            //至少保证最小容量和minCapacity相同
            if(newCapacity - minCapacity < 0){
                newCapacity = minCapacity;
            }
            //将老数组的值赋值到新的数组
            elementData = Arrays.copyOf(elementData,newCapacity);
//            Object[] newObjects = new Object[newCapacity];
//            for (int i = 0; i < elementData.length; i++) {
//                newObjects[i] = elementData[i];
//
//            }
//            elementData = newObjects;
        }
    }

System.arraycopy

System.arraycopy 是Java标准类库提供的static方法,用它复制数组比用for循环快很多。System.arraycopy针对所有类型都做了重载

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
  Object src : 原数组
   int srcPos : 从元数据的起始位置开始
  Object dest : 目标数组
  int destPos : 目标数组的开始起始位置
  int length  : 要copy的数组的长度

rangeCheck(int index)

判断下标是否越界

/**
     * 判断下标是否越界
     * @param index
     */
    private void rangeCheck(int index) {
        if (index < 0 || index >= this.size) {
            throw new IndexOutOfBoundsException("下标越界");
        }
    }

删除元素 remove

public Object remove(int index)

remove(Object o)

/**
     * 删除元素
     * @param index
     * @return
     */
    public Object remove(int index){
        rangeCheck(index);
        //使用下标查询值是否存在
        Object oldObject = get(index);

        //计算后面删除元素后面的长度
        int numMoved = size - index - 1;
        //删除原理 arraycopy 往前移动数据 将最后一个置为空
        if(numMoved > 0){
            System.arraycopy(elementData, index + 1,elementData, index, numMoved);

        }
        elementData[--size] = null;
        return oldObject;
    }

    /**
     * 删除相同元素 取第一个删除
     * @param o
     * @return
     */
    public boolean remove(Object o){
        for (int index = 0; index < size; index++) {
            Object val = elementData[index];
            if (val.equals(o)) {
                remove(index);
                return true;
            }
        }
        return false;
    }

get() getsize()

/**
     * 使用下标获取元素
     * @param index
     * @return
     */
    public Object get(int index){
        rangeCheck(index);
        return elementData[index];
    }

    /**
     * 当前大小
     * @return
     */
    public int getSize(){
        return size;
    }

完整手写源码

package com.bluedot;

import com.sun.org.apache.bcel.internal.generic.RETURN;

import java.util.Arrays;

/**
 * @author Yu W
 * @version V1.0
 * @ClassName
 * @Description:
 * @date 2021/7/17 19:50
 */
public class MyArrayList {

    /**
     * 定义默认的数组容量
     */
    private final static int DEFAULT_CAPACITY = 10;
    /**
     * 底层采用数组存放数据
     */
    private Object[] elementData;

    /**
     * 实际ArrayList的大小
     */
    private int size;

    /**
     * 指定数组初始容量
     * @param initialCapacity
     */
    public MyArrayList(int initialCapacity){
        if(initialCapacity < 0){
            throw new IllegalArgumentException("初始容量不能小于0");
        }
        elementData = new Object[initialCapacity];
    }

    /**
     * 默认初始化容量为10
     */
    public MyArrayList(){
        this(DEFAULT_CAPACITY);
    }

    /**
     * 1.判断实际存放的数据容量是否大于elementData
     * 2.直接使用下标进行赋值
     *
     * @param object
     */
    public void add(Object object){
        //判断实际存放的数据容量是否大于elementData容量
        ensureExplicitCapacity(size + 1);
        elementData[size++] = object;
    }

    /**
     *
     * @param index
     * @param object
     */
    public void add(int index, Object object){
        //判断实际存放的数据容量是否大于elementData容量
        ensureExplicitCapacity(size + 1);

        System.arraycopy(elementData, index,elementData, index + 1, size - index);
        elementData[index] = object;
        size ++;
    }

    /**
     * 扩容
     * @param minCapacity 最小的扩容量 当前的size + 1
     */
    private void ensureExplicitCapacity(int minCapacity){
        if(size == elementData.length){
//            int newCapacity = 2 * size;
            //源码中的扩容
            int  oldCapacity = elementData.length;
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            //至少保证最小容量和minCapacity相同
            if(newCapacity - minCapacity < 0){
                newCapacity = minCapacity;
            }
            //将老数组的值赋值到新的数组
            elementData = Arrays.copyOf(elementData,newCapacity);
//            Object[] newObjects = new Object[newCapacity];
//            for (int i = 0; i < elementData.length; i++) {
//                newObjects[i] = elementData[i];
//
//            }
//            elementData = newObjects;
        }
    }

    /**
     * 使用下标获取元素
     * @param index
     * @return
     */
    public Object get(int index){
        rangeCheck(index);
        return elementData[index];
    }

    /**
     * 判断下标是否越界
     * @param index
     */
    private void rangeCheck(int index) {
        if (index < 0 || index >= this.size) {
            throw new IndexOutOfBoundsException("下标越界");
        }
    }

    /**
     * 当前大小
     * @return
     */
    public int getSize(){
        return size;
    }

    /**
     * 删除元素
     * @param index
     * @return
     */
    public Object remove(int index){
        rangeCheck(index);
        //使用下标查询值是否存在
        Object oldObject = get(index);

        //计算后面删除元素后面的长度
        int numMoved = size - index - 1;
        //删除原理 arraycopy 往前移动数据 将最后一个置为空
        if(numMoved > 0){
            System.arraycopy(elementData, index + 1,elementData, index, numMoved);

        }
        elementData[--size] = null;
        return oldObject;
    }

    /**
     * 删除相同元素 取第一个删除
     * @param o
     * @return
     */
    public boolean remove(Object o){
        for (int index = 0; index < size; index++) {
            Object val = elementData[index];
            if (val.equals(o)) {
                remove(index);
                return true;
            }
        }
        return false;
    }
}

标签:index,Object,int,ArrayList,elementData,基本功能,手写,public,size
来源: https://blog.csdn.net/qq_44752800/article/details/118863875