首页 > 其他分享 >模拟ArrayList(顺序表)的底层实现

模拟ArrayList(顺序表)的底层实现

时间:2023-07-22 11:23:49浏览次数:30  
标签:index arr int ArrayList list 底层 public 模拟 size

模拟ArrayLIst的底层实现

package com.tedu.api04.list;

import java.util.Objects;

/**
 * @author LIGENSEN
 * Date: 2023/7/20 11:35
 */
public class ArrayListDemo {
    public static void main(String[] args) {
        ArrList<String> list=new ArrList<>(1);
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("f");
        list.add("c");

//        list.add(0,"d");
//        list.clear();
//        list.add(4,"e");
//        list.add(2,"f");
//        list.add(4,"e");
        System.out.println(list.indexOf("d"));
        System.out.println(list.contains("c"));
        System.out.println(list.get(2));
        System.out.println(list.isEmpty());
        System.out.println(list.lastIndexOf("c"));
        list.remove(3);
        list.remove("a");
        list.set(1,"cc");
        System.out.println(list.subList(0, 1));
        list.toArray();

        System.out.println(list);
    }
}

/**
 * 用数组来实现 ArrList
 * 集合里面可以用 Object[] 存任意的数据
 *
 * @param <E>
 */
//模拟:用数组来实现ArrayList
class ArrList<E>{
    //数组
    private Object[] arr;
    //数组元素个数
    private int size;
    //初始容量
    private int initialCapacity;

    public ArrList(){
        arr=new Object[10];
    }
    //指定容量
    public ArrList(int initialCapacity){
        // 初始容量必须 > 0
        if(initialCapacity < 0){
            throw  new IllegalArgumentException("非法参数异常");
        }
        this.initialCapacity=initialCapacity;
        arr=new Object[this.initialCapacity];
    }


    //添加元素
    public void add(E e){
        //判断是否需要扩容
        if(size == arr.length)grow();
        //向第size位置上添加元素
        arr[size++]=e;
    }

    //在指定的位置插入指定的元素
    public void add(int index,E e){
        //判断下标是否越界
        if(index < 0 || index > size)
            throw new IndexOutOfBoundsException("Index:" + index +",Size" + size);
        //判断是否需要扩容
        if(size == arr.length) grow();
        //移动元素
        /*for (int i = size-1; i >= index ; i--) {
            arr[i+1]=arr[i];
        }*/
        System.arraycopy(arr,index,arr,index+1,size-index);
        arr[index]=e;
        size++;
    }

    //清空集合
    public void clear(){
        //清空每一个元素对应的引用
        for (int i = 0; i < size; i++) {
            arr[i]=null;
        }
        //重构数组
        arr=new Object[initialCapacity];
        //元素个数归零
        size=0;
    }

    //获取指定元素第一次出现的下标
    public int indexOf(E e){
        //遍历集合
        for (int i = 0; i < size; i++) {
            /**
             * 第一个 == 判断引用类型是够相等
             * arr[i].equals(e) 只能引用类型调用,判断的是值相等(重写Object 中的 equals之后)
             */
            //if(arr[i] == e || arr[i] != null && arr[i].equals(e))
            if(Objects.equals(arr[i],e))
                return i;
        }
        //如果整个循环结束,都没有return,说明没找到
        return -1;
    }
    //判断是否包含指定元素
    public boolean contains(E e){
        return indexOf(e) >= 0;
    }

    //判断越界
    private void outBounds(int index){
        if(index < 0 || index >= size)
            throw new IndexOutOfBoundsException("Index:"+index+",Size"+size);
    }

    //获取指定位置上的元素
    public E get(int index){
        //判断越界
        outBounds(index);
        //获取指定的元素
        return (E)arr[index];

    }

    //判断集合是否为空
    public boolean isEmpty(){
        return size<=0;
    }

    //获取指定元素最后一次出现的下标
    public int lastIndexOf(E e){
        for (int i = size-1; i >= 0 ; i--) {
            if (Objects.equals(arr[i],e))return i;
        }
        return  -1;
    }

    //删除指定下标上的元素
    public void remove(int index){
        //判断越界
        outBounds(index);
        //后边的元素覆盖前面的元素
        /*for (int i = index+1; i < size; i++) {
            arr[i-1]=arr[i];
        }*/
        System.arraycopy(arr,index+1,arr,index,size-(index+1));
        size--;
    }

    //删除指定元素
    public void remove(E e){
        //获取第一次出现的位置
        int index = indexOf(e);
        //判断是否存在
        if(index >= 0)remove(index);
    }

    //替换指定位置上的元素
    public void set(int index,E e){
        //越界
        outBounds(index);
        //替换
        arr[index]=e;
    }

    //获取元素个数
    public int size(){
        return  size;
    }

    //截取子列表
    public ArrList<E> subList(int fromIndex,int toIndex){
        //判断下标范围
        if(fromIndex < 0 || toIndex > size || fromIndex > toIndex)
            throw new IllegalArgumentException();
        //截取字列表
        ArrList<E> sub=new ArrList<>();
        for (int i = fromIndex; i < toIndex; i++) {
            sub.add((E)arr[i]);
        }
        return sub;
    }

    //转为数组
    public Object[] toArray(){
        //新建数组
        Object[] newArray=new Object[size];
        //赋值元素
        System.arraycopy(arr,0,newArray,0,size);
        return newArray;
    }

    //扩容
    private void grow(){
        //计算新数组的容量
        int capacity=size;
        if(size < 2)
            capacity +=1;
        else
            capacity=size + (size >> 1);
        //构建新的数组
        Object[] arr=new Object[capacity];
        //将原来数组中的元素赋值到新的数组中
        System.arraycopy(this.arr,0,arr,0,size);
        this.arr=arr;
    }

    //转为字符传
    @Override
    public String toString() {
        //判断集合是否为空
        if(size <= 0) return "[]";
        //拼接元素
        StringBuilder sb=new StringBuilder("[");
        for (int i = 0; i < size; i++) {
            sb.append(arr[i]).append(", ");
        }
        //转为字符串
        String str = sb.toString();
        //去掉尾部的", "
        str=str.substring(0,str.length()-2);
        //返回
        return str += "]";
    }
}

运行结果如下:

image-20230722110544467

标签:index,arr,int,ArrayList,list,底层,public,模拟,size
From: https://www.cnblogs.com/lgs888/p/17573034.html

相关文章

  • 2023 暑假集训模拟赛题解
    目录CSP模拟1CSP模拟2FSYOCSP模拟1来自学长的馈赠2.CSP模拟2F考虑\(x\)只能在\(a_1\oplusb_i\)里选,那么分别代入暴力检验即可.时间复杂度\(\tilde\Theta(n^2)\),可以通过.S考虑交换同色的部分一定不优,所以同色字符的相对位置一定是不变的.那么操作序列......
  • nesp华为设备模拟器-->静态路由两个网段互联
    静态路由配置,需求如下,PC2需要访问Server1服务器。 软件安装:我下载的是hwmnqensp.rar这个安装包,他是一个整体,不像官网下载那么多包。分析:这里client终端和server服务器,自行配置ip、掩码和网关,LSW二次交换机无需配置;AR1和AR4为路由器,所以需要配置。基础命令:进入用户视图<......
  • 7824. 【2023.07.20NOI模拟】哈密顿路
    Description大家最喜欢的典中典环节它来了。在图论中,无向图的哈密顿路径是恰好能将图中所有顶点各访问一次的路径。给定一张\(n\)个点的简单无向图。对于每个\(1\leqx,y\leqn(x\neqy)\),你想要知道,是否存在一条以顶点\(x\)为起点,以顶点\(y\)为终点的哈密顿路径......
  • RTL-SDR(RTL-2832)的模拟前端硬件结构分析
    最近在学习各种模拟前端的结构,对SDR设备的前端做了一些研究,故写一篇笔记记录一下各种SDR的前端结构。首先当然是从最简单的RTL-SDR入手。对于没有接触过软件无线电的同学,先来介绍一下RTL-SDR。RTL-SDR是一种非常便宜的接收机,可用作基于计算机的无线电频谱仪,用于接收您所在......
  • CSP模拟1
    又双叒叕考试了反思可以更好的总结所以要写反思目录A.随B.单C.题D.DP搬运工1A.随题解:发现模数很特殊,m很大,n好像没什么用,先考虑部分分,暴力枚举,但是m太大了,这种情况要是直接转移肯定不行,必然是根号或者\(log\),然后就想到倍增,暴力合并块反思:考场上倍增的想法挺好想的的,以前就......
  • IDEA 中 模拟并发的工具类CountDownLatch
    (44条消息)用CountDownLatch最大限度的模拟多线程并发执行案例全案例_countdownlatch模拟高并发_@来杯咖啡的博客-CSDN博客......
  • Visual Components 3D模拟仿真软件 衡祖仿真
    VisualComponents是一款数字规划工具,涵盖营销、规划、到生产的整合平台。无论从制程规划、生产到营销都能够整合在单一平台上作业,有助于内部的技术沟通及外部营销推广。除此之外,VC软件整合了物流及智能机器人模拟功能,帮助企业在研发早期即可进行产能确认,减少不必要的成本支出和......
  • [Javascript] [] is ArrayList
    Runthefollowingcode,foundthatfor get&push&pop,itisO(1)time;Butfor shift/unshfit,itisO(n)time.Inthiscases,Javascript's[],isaArrayList,everytimeyoudoshiftorunshiftitneedtomovetherestofitemsbyoneoffw......
  • 模拟scsi盘插拔盘
    1.使用ll/sys/block命令查看磁盘编号,确认需要拔出的磁盘的编号,如0010;2.使用命令echo“scsiremove-single-device0010”>/proc/scsi/scsi模拟拔出一块磁盘;3.使用命令echo“scsiadd-single-device0010”>/proc/scsi/scsi将磁盘插回去。......
  • 使用@WebMvcTest--使用MockMvc框架来模拟HTTP请求进行测试--实现对单个控制器的http模
    1.优点无需启动内置服务器就可以对Controller中某一个HTTP接口进行测试,减少电脑内存占用和运行springboot时间消耗2.控制器类简单的方法packagecom.xurong.chapter4_test.controller;importcom.xurong.chapter4_test.Entity.Book;importcom.xurong.chapter4_test.reposit......