手写ArrayList和LinkedList

news2025/6/5 4:06:21

项目仓库:https://gitee.com/bossDuy/hand-tear-collection-series
基于b站up生生大佬:https://www.bilibili.com/video/BV1Kp5tzGEc5/?spm_id_from=333.788.videopod.sections&vd_source=4cda4baec795c32b16ddd661bb9ce865

LinkedList

package com.yb0os1.List;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;

public class MyLinkedList<E> implements List<E> {

    private int size;
    private Node<E> tail;//尾节点
    private Node<E> head;//头节点

    @Override//尾插法
    public void add(E element) {
        Node<E> node = new Node<>(tail, element, null);//尾插法
        if (tail != null) tail.next = node;
        else head = node;
        tail = node;
        ++size;
    }

    @Override//对应的下标插入元素
    public void add(E element, int index) {
        //先判断index是否合法
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException("index:" + index + "size:" + size);
        }
        //尾插
        if (size == index) {
            add(element);
            return;
        }
        //中间插入 先找到在那个位置插入
        Node<E> indexNode = findNode(index);
        Node<E> newNode = new Node<>(indexNode.prev, element, indexNode);
        if (indexNode.prev == null) {//代表indexNode是头节点
            head = newNode;
        } else {
            indexNode.prev.next = newNode;
        }
        indexNode.prev = newNode;
        ++size;
    }

    private Node<E> findNode(int index) {
        Node<E> cur = head;
        while (index-- > 0) {
            cur = cur.next;
        }
        return cur;
    }

    @Override
    public E remove(int index) {
        //先判断index是否合法
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("index:" + index + "size:" + size);
        }
        //找到要删除的节点
        Node<E> indexNode = findNode(index);
        if (indexNode.prev == null) {//头节点
            head = indexNode.next;
        } else{//非头节点
             indexNode.prev.next = indexNode.next;
        }
        if (indexNode.next == null) {//尾节点
            tail = indexNode.prev;
        } else {//非尾节点
            indexNode.next.prev = indexNode.prev;
        }
        indexNode.next = null;
        indexNode.prev = null;
        --size;
        return indexNode.value;
    }

    @Override
    public boolean remove(E element) {
        Node<E> curNode = head;
        int index = 0;
        while (curNode != null) {
            if (Objects.equals(element, curNode.value)) {
                remove(index);
                return true;
            }
            ++index;
            curNode = curNode.next;
        }
        return false;
    }

    @Override
    public E set(E element, int index) {
        //先判断index是否合法
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("index:" + index + "size:" + size);
        }
        Node<E> indexNode = findNode(index);
        E oldValue = indexNode.value;
        indexNode.value = element;
        return oldValue;
    }

    @Override
    public E get(int index) {
        //先判断index是否合法
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("index:" + index + "size:" + size);
        }
        Node<E> indexNode = findNode(index);
        return indexNode.value;
    }


    @Override
    public int size() {
        return size;
    }


    /**
     * Returns an iterator over elements of type {@code T}.
     *
     * @return an Iterator.
     */
    @Override
    public Iterator<E> iterator() {
        return new LinkedListIterator();
    }

    private class LinkedListIterator implements Iterator<E> {
        Node<E> curNode = head;
        @Override
        public boolean hasNext() {
            return curNode!=null;
        }

        /**
         * Returns the next element in the iteration.
         *
         * @return the next element in the iteration
         * @throws NoSuchElementException if the iteration has no more elements
         */
        @Override
        public E next() {
            if (curNode==null){
                 throw new NoSuchElementException();
            }
            E value = curNode.value;
            curNode = curNode.next;
            return value;
        }
    }

    private class Node<E> {
        E value;
        Node<E> next;//后继
        Node<E> prev;//前驱

        public Node(E value) {
            this.value = value;
        }

        public Node(Node<E> prev, E value, Node<E> next) {
            this.value = value;
            this.next = next;
            this.prev = prev;
        }
    }
}

ArrayList

package com.yb0os1.List;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;

public class MyArrayList<E> implements List<E> {
    private Object[] table;//默认
    private final static int DEFAULT_CAPACITY = 10;//默认容量
    private int size;//实际的大小

    public MyArrayList() {
        this.table = new Object[DEFAULT_CAPACITY];
    }

    public MyArrayList(int initialCapacity) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: " +
                    initialCapacity);
        this.table = new Object[initialCapacity];
    }

    //插入一个元素,在size的位置插入元素 也就是尾端插入元素
    @Override
    public void add(E element) {
        //先判断size是否等于容量,等于的话需要先扩容,不等于才可以插入
        if (size >= table.length) {
            resize();
        }
        table[size++] = element;
    }

    //在对应的index插入元素
    @Override
    public void add(E element, int index) {
        //先判断index是否合法
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        //判断是否需要扩容后
        if (table.length == size) {
            resize();
        }
        //插入逻辑,也就是在0~size的位置插入元素了 需要后移
        System.arraycopy(table, index, table, index + 1, size - index);
        table[index] = element;
        size++;
    }

    //删除对应下标位置的元素
    @Override
    public E remove(int index) {
        System.out.println( "remove(int index)");
        //先判断index是否合法
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        E oldElement = (E) table[index];
        System.arraycopy(table, index + 1, table, index, size - index - 1);
        table[--size] = null;
        return oldElement;
    }

    @Override
    public boolean remove(Object element) {
        System.out.println( "remove(Object element)");
        for (int i = 0; i < size; i++) {
            if (Objects.equals(element, table[i])) {
                remove(i);
                return true;
            }
        }
        return false;
    }


    //修改下标为index位置的元素为element
    @Override
    public E set(E element, int index) {
        //先判断index是否合法
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        E oldElement = (E) table[index];
        table[index] = element;
        return oldElement;
    }

    @Override
    public E get(int index) {
        //先判断index是否合法
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        return (E) table[index];
    }

    @Override
    public int size() {
        return this.size;
    }

    //数组扩容的逻辑
    private void resize() {
        //1.5倍扩容
        Object[] newTable = new Object[table.length + (table.length >> 1)];
        System.out.println("扩容了,原数组大小" + table.length + ",现在数组大小" + newTable.length);
        // 从内存的角度把一个数组元素的引用装到另外一个数组上
        System.arraycopy(table, 0, newTable, 0, table.length);
        this.table = newTable;
    }

    /**
     * Returns an iterator over elements of type {@code T}.
     *
     * @return an Iterator.
     */
    @Override
    public Iterator<E> iterator() {
        return new ArrayIterator();
    }

    private class ArrayIterator implements Iterator<E> {
        int cursor = 0;

        //判断是否有下一个元素
        @Override
        public boolean hasNext() {
            return cursor != size;
        }

        @Override
        public E next() {
            if (!hasNext())throw new NoSuchElementException();
            return (E) table[cursor++];
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2396775.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

95套HTML高端大数据可视化大屏源码分享

概述​​ 在大数据时代&#xff0c;数据可视化已成为各行各业的重要需求。这里精心整理了95套高端HTML大数据可视化大屏源码&#xff0c;这些资源采用现代化设计风格&#xff0c;可帮助开发者快速构建专业的数据展示界面。 ​​主要内容​​ ​​1. 设计风格与特点​​ 采用…

scale up 不能优化 TCP 聚合性能

scale up 作为一种系统扩展优化的方法&#xff0c;旨在提高系统组件的执行效率&#xff0c;比如替换更高性能的硬件或算法。是否可以此为依据优化 TCP 呢&#xff0c;例如通过多条路径聚合带宽实现吞吐优化(对&#xff0c;还是那个 MPTCP)&#xff0c;答案是否定的。 因为 TCP…

Python-matplotlib库之核心对象

matplotlib库之核心对象 FigureFigure作用Figure常用属性Figure常用方法Figure对象的创建隐式创建&#xff08;通过 pyplot&#xff09;显式创建使用subplots()一次性创建 Figure 和 Axes Axes&#xff08;绘图区&#xff09;Axes创建方式Axes基本绘图功能Axes绘图的常用参数Ax…

Linux 脚本文件编辑(vim)

1. 用户级配置文件&#xff08;~/.bashrc&#xff09; vim ~/.bashrc # 编辑 source ~/.bashrc # 让编辑生效 ~/.bashrc 文件是 Bash Shell 的配置文件&#xff0c;用于定义用户登录时的环境变量、别名、函数等设置。当你修改了 ~/.bashrc 文件后&#xff0c;通常需要重新…

学习BI---基本操作---数据集操作

什么是数据集&#xff0c; 数据集&#xff08;Dataset&#xff09;​​ 是指从原始数据源&#xff08;如数据库、Excel、API等&#xff09;提取并经过标准化处理后的数据集合&#xff0c;通常以二维表形式存储&#xff0c;用于支撑报表、仪表盘等可视化分析。 数据集在QuickB…

初学大模型部署以及案例应用(windows+wsl+dify+mysql+Ollama+Xinference)

大模型部署以及案例应用&#xff08;windowswsldifymysqlOllamaXinference&#xff09; 1.wsl 安装①安装wsl②测试以及更新③安装Ubuntu系统查看系统以及版本安装Ubuntu系统进入Ubuntu系统 2、docker安装①下载安装包②安装③docker配置 3、安装dify①下载dify②安装③生成.en…

Redis部署架构详解:原理、场景与最佳实践

Redis部署架构详解&#xff1a;原理、场景与最佳实践 Redis作为一种高性能的内存数据库&#xff0c;在现代应用架构中扮演着至关重要的角色。随着业务规模的扩大和系统复杂度的提升&#xff0c;选择合适的Redis部署架构变得尤为重要。本文将详细介绍Redis的各种部署架构模式&a…

C++哈希表:unordered系列容器详解

本节目标 1.unordered系列关联式容器 2.底层结构 3.模拟实现 4.哈希的应用 5.海量数据处理面试题 unordered系列关联式容器 在c98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在查询时效率可以达到logN&#xff0c;即最差的情况下需要比较红…

WordPress通过简码插入bilibili视频

发布于&#xff1a;Eucalyptus-Blog 一、前言 B站是国内非常受欢迎的视频分享平台&#xff0c;上面不仅内容丰富&#xff0c;而且很多视频制作精良、趣味十足。很多人&#xff0c;比如我&#xff0c;就喜欢将B站的视频通过 iframe 嵌入到自己的网页中&#xff0c;但这段代码又…

ZLG ZCANPro,ECU刷新,bug分享

文章目录 摘要 📋问题的起因bug分享 ✨思考&反思 🤔摘要 📋 ZCANPro想必大家都不陌生,买ZLG的CAN卡,必须要用的上位机软件。在汽车行业中,有ECU软件升级的需求,通常都通过UDS协议实现程序的更新,满足UDS升级的上位机要么自己开发,要么用CANoe或者VFlash,最近…

黑马k8s(十七)

一&#xff1a;高级存储 1.高级存储-pv和pvc介绍 2.高级存储-pv 3.高级存储-pvc 最后一个改成5gi pvc3是没有来绑定成功的 pv3没有绑定 删除pod、和pvc&#xff0c;观察状态&#xff1a; 4.高级存储-pc和pvc的生命周期 二&#xff1a;配置存储 1.配置存储-ConfigMap 2.配…

掌握HttpClient技术:从基础到实战(Apache)

目录 前言 一、Apache HttpClient简介 二、HttpClient基础使用 1. 添加依赖 2. 创建HttpClient实例 3. 发送GET请求 4. 发送POST请求 三、HttpClient高级配置与实战案例 1. 连接池优化 2. 超时与重试配置 3. 文件上传&#xff08;Multipart&#xff09; 总结 前言 …

sql知识梳理(超全,超详细,自用)

目录 通识 查询的基本语法 数据库&#xff08;database&#xff09;操作 表&#xff08;table&#xff09;的操作 表中列的操作 索引操作 表中行的操作 insert into语句 update语句 删除语句 select语句 表与表之间的关系 连接查询 子查询 视图 数据备份与还原 …

[ Qt ] | QPushButton常见用法

目录 绑定键盘快捷键 前面已经说了很多用法了&#xff0c;下面主要说说绑定键盘&#xff0c;设置Icon图片。 绑定键盘快捷键 实现四个按钮&#xff0c;可以使用wsad来控制另一个按钮的上下左右的移动。 #include "widget.h" #include "ui_widget.h"Wid…

电脑驱动程序更新工具, 3DP Chip 中文绿色版,一键更新驱动!

介绍 3DP Chip 是一款免费的驱动程序更新工具&#xff0c;可以帮助用户快速、方便地识别和更新计算机硬件驱动程序。 驱动程序更新工具下载 https://pan.quark.cn/s/98895d47f57c 软件截图 软件特点 简单易用&#xff1a;用户界面简洁明了&#xff0c;操作方便&#xff0c;…

【机器学习基础】机器学习入门核心:数学基础与Python科学计算库

机器学习入门核心&#xff1a;数学基础与Python科学计算库 一、核心数学基础回顾1. 函数与导数2. Taylor公式3. 概率论基础4. 统计量5. 重要定理6. 最大似然估计&#xff08;MLE&#xff09;7. 线性代数 二、Python科学计算库精要1. NumPy&#xff1a;数值计算核心2. SciPy&…

上交具身机器人的视觉运动导航!HTSCN:融合空间记忆与语义推理认知的导航策略

作者&#xff1a;Qiming Liu 1 ^{1} 1, Guangzhan Wang 2 ^{2} 2, Zhe Liu 3 , 4 ^{3,4} 3,4 and Hesheng Wang 1 , 3 , 5 , 6 ^{1,3,5,6} 1,3,5,6单位&#xff1a; 1 ^{1} 1上海交通大学自动化系&#xff0c; 2 ^{2} 2上海交通大学软件学院&#xff0c; 3 ^{3} 3上海交通大学教…

【C++并发编程01】初识C++并发编程

1、并发是什么 并发是指两个或更多独立的活动同时发生&#xff0c;现实生活中常见的并发场景如边吃饭边看手机。 1.1、计算机中的并发&#xff1a; 计算机领域的并发是指在单个系统里同时执行多个独立的任务&#xff0c;而非顺序的进行一些活动。 我们在电脑上能够边听音乐边和…

Mysql库的操作和表的操作

Mysql库和表的操作 库的操作1.查看数据库列表2.创建数据库3.使用数据库4.查看当前在那个数据库中5.显示数据库的创建语句6.修改数据库7.删除数据库8.备份和恢复数据库9.查看数据的连接情况(简单来说就是查看有多少人使用你的数据库) 表的操作1.创建表2.查看表结构3.修改表本身(…

LangChain-结合GLM+SQL+函数调用实现数据库查询(三)

针对 LangChain-结合GLM+SQL+函数调用实现数据库查询(二)-CSDN博客 进一步简化 通过 LangChain 和大语言模型(GLM-4)实现了一个 AI 代理,能够根据自然语言提问自动生成 SQL 查询语句,并连接 MySQL 数据库执行查询,最终返回结果。 整个流程如下: 用户提问 → AI 生成 SQ…