Java中ArrayList的底层实现

本文探讨了Java中ArrayList的实现原理,重点关注其作为数组的底层结构和操作,如数组越界、扩容,通过阅读源代码解释关键方法如add、get、set和remove的实现,并讨论了arraycopy在扩容中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

List接口中的子类ArrayList底层实现是数组,因此本文我们通过阅读源代码,来自己实现ArraylList,以帮助更好的理解。

所有ArrayList中的方法,都可以归结为对数组的操作。

在对数组进行操作时,需要重点考虑数组越界以及数组扩容问题。Java中提供了arraycopy()很方便的实现了数组的扩容。

本文未能全部实现List中的所有接口,主要实现了以下方法:

  1. 构造方法
  2. isEmpty()
  3. add(Object obj)、add(int index,Object obj)
  4. get(int index)
  5. set(int index,Object obj)
  6. remove(int index),remove(Object obj)
/**
 * 自己实现一个ArrayList,更好的理解ArrayList类的底层结构
 */
package cn.zhouxj.collection;

import java.util.ArrayList;
import java.util.List;

public class MyArrayList {

    private Object[] elementData;//ArrayList 的底层实现依赖于数组,所有的方法都是对这个数组进行操作
    private int size;//size表示数字元素的个数,注意区分数组中的length。length表示有多少车位,size表示停了多少车
    public int size(){
        return size;
    }

    //构造方法
    public MyArrayList(){
        this(10);//默认数组长度为10

    }
    public MyArrayList(int initialCapacity){
        //捕获异常
        if(initialCapacity<0) {
            try {
                throw new Exception();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        elementData = new Object[initialCapacity];//新建一个数组
    }

    //自己实现add(),在末尾插入
    public void add(Object obj){
        //考虑数组扩容的问题,数组初始化默认长度为10,此处实现数组扩容
        //所谓扩容就是找一个新的数组,将原来的元素复制进去
        if(size==elementData.length){
            Object [] newArray = new Object[size*2+1];//新建一个数组,大小是原来数组的2倍加1
            //将原来数组的内容拷贝到新的数组
            //两种方法,使用arraycopy(),或者自己写一个循环
            System.arraycopy(elementData,0,newArray,0,elementData.length);

           /* for(int i =0;i<elementData.length;i++){
                newArray[i] = elementData[i];
            }*/
            elementData = newArray;
        }
        elementData[size] = obj;
        size++;
    }
    //自己实现add。在指定位置插入元素
    public void add(int index,Object obj){
        rangeCheck(index);

        //此处需要考虑数组是否需要扩容
        //代码同上add()此处省略

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

    //自己实现isEmpty()
    public boolean isEmpty(){
        if(size()==0){
            return true;
        }
        else{
            return false;
        }
    }

    //自己实现get()
    public Object get(int index) {
        rangeCheck(index);
        return elementData[index];
    }
    //自己实现remove,删除指定位置的对象(其实就是数组的删除操作)
    public void remove(int index){
        rangeCheck(index);

        //使用arraycopy方法
        System.arraycopy(elementData,index+1,elementData,index,size-index-1);
        elementData[--size]=null;
    }
    //删除指定的对象,只删除查到的第一个obj
    public void remove(Object obj){
        for(int i=0;i<size;i++){
            if(get(i).equals(obj)){//注意此处底层实现是用的equals(),而不是==
                remove(i);
            }
        }

    }
    //自己实现set()方法
    public Object set(int index,Object obj){
        rangeCheck(index);
        Object oldValue = elementData[index];
        elementData[index] = obj;
        return oldValue;
    }

    private void rangeCheck(int index){
        if (index >= size) {
            try {
                throw new Exception();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


    }
    public static void main(String[] args){
        MyArrayList list = new MyArrayList(3);
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("ddd");
        list.add("aaa");
        list.add("bbaaab");

        System.out.println(list.size());
        System.out.println(list.get(1));

        list.remove(3);;
        list.remove("ddd");
        System.out.println(list.size());

        list.set(0,"abxc");

        for(int i = 0;i<list.size();i++)
        System.out.println(list.get(i));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值