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

这篇具有很好参考价值的文章主要介绍了模拟ArrayList(顺序表)的底层实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

模拟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 += "]";
    }
}

运行结果如下:

模拟ArrayList(顺序表)的底层实现文章来源地址https://www.toymoban.com/news/detail-594416.html

到了这里,关于模拟ArrayList(顺序表)的底层实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java--数据结构】模拟实现ArrayList

    欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 LIst 顺序表ArrayList 顺序表优点 IList接口 ArrayList中定义要操作的数组 在MyArrayList中 重写接口方法 新增元素 在指定位置插入元素  pos不合法异常 判断和查找元素 获取和更新元素 删除元素和清空顺序

    2024年04月25日
    浏览(26)
  • ArrayList 底层结构和源码分析

    ArrayList 实现了 List 接口。它可以存储包括 null 的任何类型的对象,允许重复元素。 ArrayList 在内部使用一个数组来存储元素,当元素数量超过数组容量时, ArrayList 会自动重新分配更大的内部数组,并且将现有元素复制到新数组中。 ArrayList 基本等同于 Vector ,但是 ArrayList 是

    2024年02月08日
    浏览(28)
  • ArrayList底层结构和源码分析

    1.permits all elements, including null,ArrayList 可以加入null,并且多个 2.ArrayList是由数组来实现数据存储的 3.ArrayList 基本等同于Vector,除了ArrayList是线程不安全(执行效率高)看源码.在多线程情况下,不建议使用ArrayList 代码演示: ArrayList的底层操作机制源码分析 (重点,难点.) 1.Arra

    2023年04月24日
    浏览(46)
  • ArrayList 底层结构及源码分析

    ArrayList 实现了 List 接口。它可以存储包括 null 的任何类型的对象,允许重复元素。 ArrayList 在内部使用一个数组来存储元素,当元素数量超过数组容量时, ArrayList 会自动重新分配更大的内部数组,并且将现有元素复制到新数组中。 ArrayList 基本等同于 Vector ,但是 ArrayList 是

    2024年02月08日
    浏览(32)
  • Java中ArrayList的底层扩容机制和Vector的底层扩容机制,以及ArrayList和Vector的对比与选择。附源码

    在 Java 的 ArrayList 中,当数组的容量不足以存储新元素时,会触发扩容操作。ArrayList 的底层使用数组来存储元素,而扩容机制主要涉及到创建一个更大的数组,并将现有元素复制到新数组中。ArrayList 支持无参扩容和有参扩容两种机制。 无参扩容机制 : 无参扩容是指 首次的

    2024年02月11日
    浏览(27)
  • ArrayList与顺序表

    顺序表是用一段 物理地址连续 的存储单元依次存储数据元素的线性结构,一般情况下采用 数组 存储。在数组上完成数据的增删查改。 在集合框架中,ArrayList是一个普通的类,实现了List接口,它有以下几个特点: ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动

    2024年02月11日
    浏览(31)
  • 【Java】顺序表ArrayList

    顺序表(Sequential List)是一种基本的数据结构,它由一组连续的存储空间(例如数组)来表示线性表的数据结构。顺序表中的元素在内存中是按照其逻辑顺序依次储存的。 顺序表具有以下特点: 元素在内存中的储存是连续的,可以通过下标直接访问和定位元素。 元素之间的

    2024年02月12日
    浏览(32)
  • 06.ArrayList与顺序表

    线性表 ( linear list ) 是 n个具有相同特性的数据元素的有限序列 。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列... 线性表在 逻辑上是 线性 结构 ,也就说是连续的一条直线。但是在 物理结构上并不一定是连续的 ,线性表在物理上

    2023年04月09日
    浏览(25)
  • 第五章 ArrayList与顺序表

    线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结 构,常见的线性表:顺序表、链表、栈、队列… 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物 理上存储时,

    2024年02月06日
    浏览(22)
  • java 数据结构 ArrayList源码底层 LinkedList 底层源码 迭代器底层

    对于数据结构我这边只告诉你右边框框里的 栈的特点:后进先出,先进后出,入栈也成为压栈,出栈也成为弹栈 栈就像一个弹夹 队列先进先出后进后出 队列像排队 链表查询满 但是增删快(相对于数组而言) 拓展:还有一个双向链表 他在查询元素的时候更快些,因为他在拿到一个元素

    2024年02月05日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包