简单重写ArrayList个别方法

ArrayList详解
本文深入解析了ArrayList的底层实现机制,包括其动态数组结构、索引查询效率、扩容原理及实现细节。同时,提供了自定义ArrayList类的完整代码示例,涵盖接口、迭代器实现及常用方法。

首先简单回顾一下ArrayList
特点:在内存中分配连续的空间,只存储数据,不存储地址信息,位置就隐含地址。
底层结构:一个长度可以动态增长的数组
优点:1.节省存储空间,因为分配给数据的存储单元,全都用来存放节点的数据,节点之间的逻辑关系并没有占用额外的空间
2.索引查询效率高,每一个节点对应一个序号,该序号可以通过计算公式得到节点地址(通俗来说 一个长度为5的数组 首节点的地址为100 ,那么一个节点占用4个字节,第4个节点的地址即为100+4x4=116)
缺点:1.增加删除效率低,需要一个一个的位移元素
2.必须提前分配固定数量的空间 ,如果存储数据少了就造成空间的浪费
3.按照内容查询效率低 因为需要一个一个比较

通过无参构造方法创建对象时 JDK7默认给定长度为10 ,JDK8默认给的长度为0,添加元素时在给长度 10

长度不够时每次扩容50% 扩容原理:当空间不足时会创建一个新的数组 默认长度是之前长度的2倍,然后把原数组的内容拷贝到新的数组中 在把地址指向原数组
好了,废话不多说上代码了(***如果代码有问题的话,请留言!!!***)
先创建一个模拟需要实现的接口

  /**
     * 模拟list实现接口
     */
    public interface List {
        // 返回线性表的大小,即数据元素的个数。
        public int size();
        // 返回线性表中序号为 i 的数据元素 根据下标获取元素
        public Object get(int i);
        // 如果线性表为空返回 true,否则返回 false。判断是否为空
        public boolean isEmpty();
        // 判断线性表是否包含数据元素 e 判断集合中是否包含某元素
        public boolean contains(Object e);
        // 返回数据元素 e 在线性表中的序号 返回指定元素的下标
        public int indexOf(Object e);
        // 将数据元素 e 插入到线性表中 i 号位置 插入到指定下标的位置
        public void add(int i, Object e);
        // 将数据元素 e 插入到线性表末尾 添加元素
        public void add(Object e);
        // 将数据元素 e 插入到元素 obj 之前 将指定元素插入到标记元素之前
        public boolean addBefore(Object obj, Object e);
        // 将数据元素 e 插入到元素 obj 之后 将指定元素插入到标记元素之后
        public boolean addAfter(Object obj, Object e);
        // 删除线性表中序号为 i 的元素,并返回之 删除指定下标的元素
        public Object remove(int i);
        // 删除线性表中第一个与 e 相同的元素 删除第一个元素为e 的数据
        public boolean remove(Object e);
        // 替换线性表中序号为 i 的数据元素为 e,返回原数据元素 替换下标中的元素为指定元素
        public Object replace(int i, Object e);
        public Iterator iterator(); //实现迭代器
    
    }

创建迭代器接口

public interface Iterator<T> {

    boolean hasNext();

    T next();

}

实现ArratList接口中的常用方法

/**
 * 实现ArrayList 相关功能
 */
public class ArrayList implements List {

    private transient Object[] elementData; //ArrayList底层是一个长度可以动态增长的数组

    private int size = 0; //集合中元素的个数,不是数组分配了多少个空间

    public ArrayList(){
        //this(10);//JDK7的原理
        elementData=new Object[10];
    }

    public ArrayList(int initialCapacity){
        if(initialCapacity<0){
            throw new IllegalArgumentException("输入的参数不能小于0: "+initialCapacity);
        }
        elementData=new Object[initialCapacity];
    }



    /**
     * 获取数组长度
     * @return
     */
    @Override
    public int size() {
        return size;
    }

    /**
     * 获取指定下标的元素值
     * @param i 指定下标
     * @return
     */
    @Override
    public Object get(int i) {
        if(i<0||i>=size){
            throw new RuntimeException("数组索引越界异常:"+i);
        }
        return elementData[i];
    }

    /**
     * 判断数组是否为空
     * @return
     */
    @Override
    public boolean isEmpty() {
        return size==0;
    }

    /**
     * 判断数组中是否包含某元素
     * @param e 指定元素
     * @return
     */
    @Override
    public boolean contains(Object e) {
        return indexOf(e)!=1;
    }

    /**
     * 根据指定元素 返回该元素在数组中的下标
     * @param e
     * @return
     */
    @Override
    public int indexOf(Object e) {
        int index=-1;//表示不存在
        for (int i=0;i<size;i++){
            if(elementData[i].equals(e)){
                index=i;
                break;
            }
        }

        return index;
    }

    /**
     * 添加元素到指定的下标处
     * @param i
     * @param e
     */
    @Override
    public void add(int i, Object e) {
        //如果数组长度满了 扩充
        if (size==elementData.length){
            elementData= Arrays.copyOf(elementData,size*2);
        }
        //后移后面的元素
        for(int index = size-1; index >=i; index-- ){
            elementData[index+1] = elementData[index];
        }
        //添加元素
        elementData[i]=e;
        //数组长度自增
        size++;

    }

    /**
     * 添加元素到数组末尾
     * @param e
     */
    @Override
    public void add(Object e) {
        //如果数组长度满了需要扩容
        if(size==elementData.length){
//            //创建一个新的数组 数组的长度是原数组的长度的2倍
//            Object[] newArray=new Object[size*2];
//            //把原数组中的元素拷贝到新数组中
//            for (int i = 0; i <size; i++) {
//                newArray[i]=elementData[i];
//            }
//            //把新数组指定给原数组
//            elementData=newArray;
            elementData= Arrays.copyOf(elementData,size*2);//优化上面数据
        }
        //添加元素到数组末尾
        elementData[size]=e;
        //数组长度自增
        size++;

    }

    /**
     * 添加元素到数组某个元素之前
     * @param obj
     * @param e
     * @return
     */
    @Override
    public boolean addBefore(Object obj, Object e) {
        return false;
    }

    /**
     * 添加元素到标记元素之后
     * @param obj
     * @param e
     * @return
     */
    @Override
    public boolean addAfter(Object obj, Object e) {
        return false;
    }

    /**
     * 根据指定下标删除指定元素
     * @param i
     * @return
     */
    @Override
    public Object remove(int i) {
        return null;
    }

    /**
     * 根据元素值删除数组中第一个值为e的元素
     * @param e
     * @return
     */
    @Override
    public boolean remove(Object e) {
        return false;
    }

    /**
     * 根据指定的下标替换为指定的元素
     * @param i
     * @param e
     * @return
     */
    @Override
    public Object replace(int i, Object e) {
        return null;
    }

    /**
     * 实现迭代器
     * @return
     */
    @Override
    public Iterator iterator() {
        return new Itr();
    }

    /**
     * 重写toStirng
     * @return
     */
    @Override
    public String toString() {
        StringBuilder stringBuilder=new StringBuilder("[");
        for (int i=0;i<=size-1;i++){
            stringBuilder.append(elementData[i]+",");
        }
        if(size>0){
            stringBuilder.deleteCharAt(stringBuilder.length()-1);
        }
        stringBuilder.append("]");
        return stringBuilder.toString();
    }
    //使用内部类,可以直接访问外部类的成员变量
    private class Itr<T> implements Iterator<T> {
        int cursor =0;//默认值是0,用来指向当前元素,默认指向第0个
        @Override
        public boolean hasNext() {
            return cursor<size;
        }

        @Override
        public T next() {
            int i = cursor;
            if(i>=size){
                throw new NoSuchElementException("没有这个元素了,cursor:"+i);
            }
            cursor++;

            return (T)elementData[i];
        }
    }

}

测试方法

public class Test {
    public static void main(String[] args) {

        List list = new ArrayList();
        //向末尾添加元素
        list.add("11111");
        list.add("aaaaa");
        list.add("bbbbb");
        list.add("33333");
        list.add("22222");
        list.add(3, "AAAAA");
        //进行各种操作验证添加
        System.out.println(list.get(3));
        System.out.println(list.size());
        System.out.println(list.isEmpty());
        System.out.println(list.contains("11111"));
        System.out.println(list.indexOf("22222"));
        System.out.println(list.toString());
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            String elem = it.next();
            System.out.println(elem);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值