Java小白一文讲清Java中集合相关的知识点(四)

news2024/10/16 15:27:51

LinkedList底层结构

  • LinkedList底层实现了双向链表和双向队列特点
  • 可以添加任意元素,包括null,元素可以重复
  • 线程不安全,没有实现同步
LinkedList底层操作机制
  • LinkedList底层维护了一个双向链表
  • LinkedList中维护了两个属性first和last分别指向首结点和尾结点
  • 每个结点(Node 对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个结点,最终实现双向链表
  • 所以LinkedList的元素的增加和删除,不是通过数组完成的,相对来说效率较高
  • 模拟一个简单的双向链表
@SuppressWarnings({"all"})
public class Journey {
    public static void main(String[] args) {
        //模拟一个简单的双向链表
        Node life = new Node("life");
        Node is = new Node("is");
        Node journey = new Node("a journey");

        //各个结点相连,形成双向链表life is a journey
        life.next = is;
        is.next = journey;

        journey.pre = is;
        is.pre = life;

        //让first引用指向jack,其就是双向链表的头结点
        Node first = life;
        //让last引用指向journey,其就是双向链表的尾结点
        Node last = journey;

        //演示,从头到尾遍历链表
        while(true){
            if(first==null){
                break;
            }
            //输出first,
            System.out.println(first);
            first = first.next;
        }
        /**
         * 输出
         * Node name=life
         * Node name=is
         * Node name=a journey
         */
        System.out.println("==========演示链表添加数据==========");
        //演示下链表添加数据/对象是多么方便
        //要求:在 life 和  is 之间添加个 definitely
        //life definitely is a journey
        Node definitely = new Node("definitely");
        definitely.next = is;
        definitely.pre = life;
        life.next = definitely;
        is.pre = definitely;
        //让first指针重新指向头结点life
        first = life;
        while (true){
            if(first==null){
                break;
            }
            System.out.println(first);
            first = first.next;
        }
    }
}
//定义一个Node 类,表示双向链表的一个结点
class Node{
    public Object item;
    public Node next;
    public Node pre;
    public Node(Object name){
        this.item = name;
    }
    public String toString(){
        return "Node name="+item;
    }
}

在这里插入图片描述

LinkedList的增删改查

@SuppressWarnings({"all"})
public class Journey {
    public static void main(String[] args) {
        LinkedList list = new LinkedList();
        //添加结点,加了0 1 2
        for (int i = 0; i <= 2; i++) {
            list.add(i);
        }

        //演示删除结点
        System.out.println(list);//[0, 1, 2]
        list.remove();//删除了0
        //此时默认删除第一个元素0,输出此时的list空间状态
        System.out.println(list);//[1, 2]
        list.add("kerwin");
        System.out.println(list);//[1, 2, kerwin]
        list.remove(1);//删除1号索引元素,即2
        System.out.println(list);//[1, kerwin]

        //修改某个结点
        list.set(1,"fun");//修改1索引处的元素为fun
        System.out.println(list);//[1, fun]

        //得到某个结点对象
        list.add("Dopamine");
        System.out.println(list.get(2));//Dopamine
        System.out.println(list.getFirst());//1
        System.out.println(list.getLast());//Dopamine

        System.out.println("==================================================");
        //实现遍历--迭代器
        //因为LinkedList是实现了List的接口的,所以也可以使用迭代器遍历
        Iterator iterator = list.iterator();
        //要想起来快捷生成的方式哟, itit
        while(iterator.hasNext()){//这里要联想到迭代器的结构哈,先判断有没有下个元素
            Object obj = iterator.next();
            System.out.println(obj);

        }
        /**
         * 输出
         * 1
         * fun
         * Dopamine
         */

        //实现遍历--增强for
        for(Object o: list){
            System.out.println("els->"+o);
        }
        /**
         * 输出
         * els->1
         * els->fun
         * els->Dopamine
         */

        //实现遍历--最normal的for循环
        for (int i = 0; i < list.size(); i++) {
            System.out.println("normal-For->"+list.get(i));
        }
        /**
         *输出
         * normal-For->1
         * normal-For->fun
         * normal-For->Dopamine
         */


    }
}
对应的各个方法的源码剖析
//增方法的源码剖析   add
    
//深入LinkedList的add方法,可知
//传入一个数进去后,先自动装箱,然后,执行add方法,源码如下:
        public boolean add(E e) {
        linkLast(e);
        return true;
    }
//继续深入linkLast方法,可得知其内部具体实现,先了解下Node类的具体内容,再往下看linkLast函数
    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

    void linkLast(E e) {
        final Node<E> l = last;//起初last为null
        final Node<E> newNode = new Node<>(l, e, null);//创建一个新结点,
        //prev为null,element就是此时的元素,next也置为null
        last = newNode;//laast指向新建结点
        if (l == null)
            first = newNode;//如果首结点为空的话,first就指向新节点,使之为首结点
        else
            l.next = newNode;//否则首结点之后才紧跟新建结点
        size++;
        modCount++;
    }


在这里插入图片描述

这时候,你会发现,加了两个元素之后,first指向第一个结点,而last指向第二个结点,这不正合心意??

//删方法的源码剖析   remove
    public E remove() {
        return removeFirst();
    }

    public E removeFirst() {
        final Node<E> f = first;
        if (f == null)//如果为空,还删啥?抛异常lou
            throw new NoSuchElementException();
        return unlinkFirst(f);//不为空,则开始操作
    }

    private E unlinkFirst(Node<E> f) {
        // assert f == first && f != null;
        final E element = f.item;
        final Node<E> next = f.next;
        f.item = null;//将第一个元素置空
        f.next = null; // help GC
        first = next;//first移动到原先头结点的next,也就是移动到了原先的第二个结点处
        if (next == null)//假如原先只有一个结点,那么next==null,
            //也就谈不上断掉下一个结点指向自己的prev了
            last = null;
        else
            next.prev = null;//倘若原先的结点不止一个,
        //那么就需要把第二个结点指向自己的prev也断开
        size--;
        modCount++;
        return element;
    }


在这里插入图片描述

ArrayList和LinkedList比较

在这里插入图片描述

如何选择ArrayList和LinkedList?

  • 如果我们改查的操作多,选择ArrayList
  • 如果我们增删的操作多,选择LinkedList
  • 一般来说,程序中,大部分是查询,因此大多数情况下,会选择ArrayList
  • 在一个项目中,根据业务灵活选择,也可能这样,有可能一个模块用的是ArrayList,另一个模块使用的是LinkedList

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

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

相关文章

如何启动vue ui,快速创建vue项目

1.查看自己是否已经安装了vue3.0脚手架版本&#xff0c;打开cmd命令框输入vue -V(大写为查看&#xff0c;此处查看的是脚手架的版本)。如果没有提示版本&#xff0c;而是命令不存在...则要进行下面的1.1操作 1.1安装Vue CIL&#xff0c;如果已安装&#xff0c;此步忽略。安装完…

计算机毕业设计选题推荐-中华诗词文化交流平台-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

快速搭建和运行Spring Boot项目的简易指南

对于非Java开发的后端开发人员而言&#xff0c;即便未曾接触过Java&#xff0c;也可能听说过Spring Boot这一框架。若想要快速搭建并运行一个Spring Boot项目&#xff0c;可以遵循以下步骤&#xff1a; 环境准备 **安装Java JDK&#xff1a;**确保您的开发环境中安装了Java J…

Android Studio编译时各类型网络超时优化方案

我们国家有很多长城&#xff0c;我觉得最重要的除了大家耳熟能详的西起嘉峪关&#xff0c;东至山海关的万里长城&#xff0c;还有一个叫GFW的国家长城防火墙&#xff0c;这个防火墙起初仅是为了禁止用户访问政治敏感信息&#xff0c;后来逐渐强大。。。目前最新进展是我们已和世…

142.环形链表二-力扣

142. 环形链表 II - 力扣&#xff08;LeetCode&#xff09; struct ListNode *detectCycle(struct ListNode *head) {struct ListNode *fasthead;struct ListNode *slowhead;while(fast && fast->next){fast fast->next->next;slow slow->next;if(fasts…

Python 使用中点查找矩形的角(Find Corners of Rectangle using mid points)

考虑一个矩形 ABCD&#xff0c;我们给出了边 AD 和 BC 中点&#xff08;分别为 p 和 q&#xff09;的坐标以及它们的长度 L&#xff08;AD BC L&#xff09;。现在给定参数&#xff0c;我们需要打印 4 个点 A、B、C 和 D 的坐标。 例子&#xff1a; 输入&#xff1a;p (1,…

人工智能在病理组学和精准医疗中的最新研究进展|顶刊速递·24-09-05

小罗碎碎念 本期推文主题&#xff1a;AI病理精准医疗 这段时间一直在尝试不同的学习道路&#xff0c;兜兜转转还是觉得&#xff0c;每天跟踪最新文献其实是很有必要的&#xff0c;并且这些最新的文献不一定非要与自己专业完全匹配&#xff0c;不然就会把自己困住。 这期推文和…

文章润色太费时?试试这5款ai写作工具

你是否曾梦想拥有一个私人编辑&#xff0c;随时随地帮你打磨文字&#xff0c;让写作变得既轻松又专业&#xff1f; 告诉你一个好消息&#xff0c;现在有5款AI写作工具&#xff0c;它们就拥有这样的能力&#xff01;这些AI助手擅长润色文章&#xff0c;优化语法&#xff0c;甚至…

微信小程序使用nfc读取

** 微信小程序开发nfc读取 ** &#xff08;注释微信官方api&#xff0c;仅支持安卓&#xff0c;不支持苹果ios&#xff09;官方文档 上代demo <template><div class"nfc"><u-navbar leftIcon"arrow-leftward" bgColor"#ffffff&qu…

网络安全服务基础Windows--第12节-域与活动目录

工作组 在Windows环境中配置⼯作组相对简单&#xff0c;适合⼩型⽹络环境&#xff0c;如家庭或⼩型办公室⽹络。⼯作组通过简单的⽹络共享和本地管理来实现资源共享&#xff0c;⽽不依赖于中央控制的服务器。 ● 定义&#xff1a;⼯作组是⼀种对等⽹络模型&#xff0c;在这种…

ASP源码 发布站改制最终版 原来3000ok网通大站的源程序

ASP源码 新服发布站改制最终版 原来3000ok网通大站的源程序 这个是非常完整 兼容性很强的。 后台地址&#xff1a;http://你的域名/admin 账号&#xff1a;admin 密码&#xff1a;admin 会员发布地址&#xff1a;http://你的域名/gamevip 源码下载&#xff1a;https://downlo…

【网络安全】IIS未授权访问敏感数据

未经许可,不得转载。 文章目录 正文攻击方法正文 IIS 是 Internet Information Services 的缩写,是微软开发的一个基于 Windows 的 Web 服务器。 HAProxy 是一个知名的高性能负载均衡器和代理服务器。它通常用于将流量分发到多个后端服务器,常与 Web 服务器(包括 IIS)一…

智匠MindCraft:一站式AI模型API调用平台

智匠MindCraft提供了一站式的AI模型解决方案&#xff0c;通过单一API接口&#xff0c;用户可以轻松调用多种主流AI模型&#xff0c;涵盖大语言模型、图片生成、视频生成、语音识别和语音合成等多个领域。以下是该平台的详细介绍&#xff1a; 1、平台概览 主页访问&#xff1a…

基于Qt设计的人脸课堂考勤机系统(219)

文章目录 一、前言1.1 项目介绍【1】开发背景【2】项目实现的功能1.2 设计思路【1】系统架构设计【2】流程设计【3】关键技术实现【2】整体构架1.3 项目开发背景【1】选题的意义【2】可行性分析【3】参考文献【4】摘要【5】项目背景1.4 开发工具的选择1.5 系统框架图1.6 系统功…

How to apply streaming in azure openai dotnet web application?

题意&#xff1a;"如何在 Azure OpenAI 的 .NET Web 应用程序中应用流式处理&#xff1f;" 问题背景&#xff1a; I want to create a web api backend that stream openai completion responses. "我想创建一个 Web API 后端&#xff0c;用于流式传输 OpenAI…

计算机领域学术会议(ICCBD+AI 2024)

第五届计算机、大数据与人工智能国际会议&#xff08;ICCBDAI 2024&#xff09;将于2024年11月1日-3日在江西景德镇召开。 本届会议由景德镇陶瓷大学主办&#xff0c;西安交通大学、暨南大学、南京邮电大学、景德镇学院、ELSP&#xff08;爱迩思出版社&#xff09;、ESBK国际学…

《中国储运》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《中国储运》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的正规学术期刊。 问&#xff1a;《中国储运》级别&#xff1f; 答&#xff1a;国家级。主管单位&#xff1a; 中储发展股份有限公司 主办单位&…

Openwrt远程唤醒Windows

OpenWrt 安装 luci-app-wol 安装 luci-app-wol&#xff0c;按下一节配置好Windows和主板。 电脑设置 参考 主板BIOS如何设置启用网络唤醒(WOL: Wake On Lan)功能远程唤醒远程控制——Windows 注意 关闭 “电源选项”下“电源按钮”的“启用快速启动”

微软的Teams只有会议号和密码怎么参会呢

客户只给了个会议邀请的截图&#xff0c;没有办法获取直接的参会链接&#xff0c;只能通过图上的会议号码和密码来进入会议&#xff0c;如果这样必须要先登录&#xff0c;但我不想登录怎么办呢&#xff1f; 可以通过以下链接来实现&#xff1a; https://www.microsoft.com/zh-c…

苹果永久删除的照片怎么恢复?这里有你需要的答案,秘籍大公开

“苹果手机里面的照片删除了怎么办&#xff1f;”相信您的第一反应一定是冲去最近删除的文件夹里&#xff0c;只需要轻轻一点就能恢复照片。但有时&#xff0c;我们已经将最近删除文件夹里的照片给清空了&#xff0c;又或者删除时间超过30天了。这时&#xff0c;苹果永久删除的…