浅聊java集合框架中的java.util.LinkedList

news2024/11/23 8:09:07

java集合框架总览

Java集合框架是一个用来代表和操纵集合的统一架构,它为管理和组织对象的集合提供了一组类和接口。这个框架包含三个主要部分:接口、实现和算法。

接口

  • Collection:这是集合框架的根接口,定义了集合的基本操作,如添加、删除、遍历等。
  • List:表示一个有序的集合(元素可以重复),它继承了Collection接口。
  • Queue:代表一种特殊的线性表,只允许在表的前端进行删除操作,而在表的后端进行插入操作。
  • Map:存储键值对(key-value pair)的集合。
  • Set:一个不包含重复元素的集合。

实现

  • ArrayList:List接口的一个实现,它使用一个数组来存储元素。ArrayList提供了快速的随机访问,但插入和删除操作可能较慢。
  • LinkedList:基于链表实现的List和Queue。它提供了快速的插入和删除操作,但随机访问可能较慢。
  • HashMap:基于哈希表实现的Map,提供了快速的键值对存储和检索。
  • TreeMap:基于红黑树实现的Map,可以对键进行排序。
  • HashSetTreeSet:都是Set接口的实现,其中HashSet基于哈希表,而TreeSet基于红黑树,可以对元素进行排序。

算法

  • 集合框架中的算法是指实现集合接口对象里的方法执行的一些有用的计算,例如搜索和排序。这些算法被称为多态,因为相同的方法可以在相似的接口上有着不同的实现。

 此外,Java集合框架还提供了一些其他重要的数据结构,如栈(Stack)和哈希表(Hash Table)。栈是一种后进先出(LIFO)的数据结构,Java中的Stack类或Deque接口的实现类(如ArrayDeque)可以用来实现栈的功能。哈希表则是一种以键值对形式存储数据的数据结构,Java中的HashMap和Hashtable等类提供了哈希表的实现。

Java集合框架的作用不仅在于提供了一种灵活且高效的方式来处理各种数据结构,包括列表、集合、映射等,还提供了丰富的数据操作和算法支持,如排序、过滤、映射、归约等,这对于数据处理非常重要。同时,它还有助于避免并发访问问题,提高程序的稳定性。

总的来说,Java集合框架是一个强大且灵活的工具,它使得Java编程在处理集合数据时更加高效和便捷。

 java.util.LinkedList

/**
 * Doubly-linked list implementation of the {@code List} and {@code Deque}
 * interfaces.  Implements all optional list operations, and permits all
 * elements (including {@code null}).
 *
 * <p>All of the operations perform as could be expected for a doubly-linked
 * list.  Operations that index into the list will traverse the list from
 * the beginning or the end, whichever is closer to the specified index.
 *
 * <p><strong>Note that this implementation is not synchronized.</strong>
 * If multiple threads access a linked list concurrently, and at least
 * one of the threads modifies the list structurally, it <i>must</i> be
 * synchronized externally.  (A structural modification is any operation
 * that adds or deletes one or more elements; merely setting the value of
 * an element is not a structural modification.)  This is typically
 * accomplished by synchronizing on some object that naturally
 * encapsulates the list.
 *
 * If no such object exists, the list should be "wrapped" using the
 * {@link Collections#synchronizedList Collections.synchronizedList}
 * method.  This is best done at creation time, to prevent accidental
 * unsynchronized access to the list:<pre>
 *   List list = Collections.synchronizedList(new LinkedList(...));</pre>
 *
 * <p>The iterators returned by this class's {@code iterator} and
 * {@code listIterator} methods are <i>fail-fast</i>: if the list is
 * structurally modified at any time after the iterator is created, in
 * any way except through the Iterator's own {@code remove} or
 * {@code add} methods, the iterator will throw a {@link
 * ConcurrentModificationException}.  Thus, in the face of concurrent
 * modification, the iterator fails quickly and cleanly, rather than
 * risking arbitrary, non-deterministic behavior at an undetermined
 * time in the future.
 *
 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
 * as it is, generally speaking, impossible to make any hard guarantees in the
 * presence of unsynchronized concurrent modification.  Fail-fast iterators
 * throw {@code ConcurrentModificationException} on a best-effort basis.
 * Therefore, it would be wrong to write a program that depended on this
 * exception for its correctness:   <i>the fail-fast behavior of iterators
 * should be used only to detect bugs.</i>
 *
 * <p>This class is a member of the
 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
 * Java Collections Framework</a>.
 *
 * @author  Josh Bloch
 * @see     List
 * @see     ArrayList
 * @since 1.2
 * @param <E> the type of elements held in this collection
 */

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

java.util.LinkedList 是 Java 集合框架中的一部分,它实现了 List 接口和 Deque 接口,用于表示一个双向链表。与 ArrayList 不同的是,LinkedList 的内部元素不是连续存储的,而是通过节点(Node)来连接各个元素。这种结构使得 LinkedList 在插入、删除操作上具有较高的效率,但在访问元素时,其效率可能较低,因为需要从头节点或尾节点开始遍历

以下是 java.util.LinkedList 的一些主要特性和方法:

主要特性

  1. 双向链表LinkedList 实现了双向链表,因此可以从头部或尾部进行插入和删除操作。
  2. 动态大小:链表的大小可以动态增长和缩小,以适应添加或删除元素的需求。
  3. 线程不安全:与 ArrayList 一样,LinkedList 的非同步实现也是线程不安全的。如果多个线程同时修改链表,可能会导致数据不一致。在多线程环境中,可以考虑使用 Collections.synchronizedList 方法来包装 LinkedList,或者使用 CopyOnWriteArrayList 作为线程安全的替代方案。

主要方法

  1. 构造方法

    • LinkedList():创建一个空的双向链表。
    • LinkedList(Collection<? extends E> c):使用指定集合的元素来创建双向链表。
  2. 添加元素

    • add(E e):在链表末尾添加元素。
    • add(int index, E element):在指定位置插入元素。
    • addAll(Collection<? extends E> c):在链表末尾添加指定集合的所有元素。
    • addAll(int index, Collection<? extends E> c):从指定位置开始,将指定集合的所有元素插入链表。
    • addFirst(E e) 和 addLast(E e)(通过 Deque 接口):在链表头部或尾部添加元素。
  3. 删除元素

    • remove(int index):删除指定位置的元素。
    • remove(Object o):删除链表中第一个出现的指定元素。
    • removeAll(Collection<?> c):删除链表中所有包含在指定集合中的元素。
    • removeFirst() 和 removeLast()(通过 Deque 接口):删除链表头部或尾部的元素。
  4. 查找和访问元素

    • get(int index):返回指定位置的元素。
    • getFirst() 和 getLast()(通过 Deque 接口):返回链表头部或尾部的元素。
    • indexOf(Object o) 和 lastIndexOf(Object o):返回指定元素在链表中首次或最后出现的位置。
  5. 其他常用方法

    • size():返回链表中元素的数量。
    • isEmpty():检查链表是否为空。
    • clear():删除链表中的所有元素。
    • contains(Object o):检查链表中是否包含指定元素。
    • iterator() 和 descendingIterator():返回链表的迭代器,用于遍历链表。
    • listIterator(int index) 和 listIterator():返回链表的列表迭代器,用于在链表中双向遍历。

使用示例

下面是一个简单的示例,演示了如何使用 LinkedList

import java.util.LinkedList;  
  
public class LinkedListExample {  
    public static void main(String[] args) {  
        LinkedList<String> list = new LinkedList<>();  
          
        // 添加元素  
        list.add("A");  
        list.add("B");  
        list.add("C");  
          
        // 访问元素  
        System.out.println(list.get(1)); // 输出 "B"  
          
        // 删除元素  
        list.remove("B");  
          
        // 遍历元素  
        for (String item : list) {  
            System.out.println(item);  
        }  
    }  
}

 这个示例展示了如何创建一个 LinkedList,添加元素,访问元素,删除元素以及遍历元素。需要注意的是,在实际开发中,应根据具体需求选择合适的集合类型,并考虑线程安全性和性能问题。

躲不掉的ArrayList与LinkedList对比

ArrayList和LinkedList在Java集合框架中都是用于存储元素的线性列表,但它们之间存在几个关键的区别,这些区别主要体现在内部数据结构、性能特性、内存占用以及线程安全性等方面。

内部数据结构

  • ArrayList:ArrayList是基于动态数组实现的。它使用一个可增长的数组来存储元素。由于数组在内存中是连续存储的,因此ArrayList在随机访问元素时非常高效。
  • LinkedList:LinkedList是基于双向链表实现的。它使用节点来存储元素,每个节点包含数据和指向前后节点的引用。这种结构使得LinkedList在插入和删除元素时更加灵活。

性能特性

  • 访问元素:由于ArrayList是基于数组的,所以通过索引访问元素(get和set操作)非常快,时间复杂度为O(1)。而LinkedList需要从头或尾开始遍历才能访问到特定位置的元素,因此其访问操作的时间复杂度为O(n)。
  • 插入和删除元素:在ArrayList中,如果在列表的中间位置插入或删除元素,可能需要移动大量的元素以保持数组的连续性,这会导致性能下降。相比之下,LinkedList的插入和删除操作只需要修改相关节点的指针指向,因此性能更好。特别是在列表的头尾位置进行插入和删除时,LinkedList的效率非常高。

内存占用

  • ArrayList在内存中占用连续的空间,因此其内存利用率相对较高。而LinkedList的每个节点除了存储数据外,还需要存储指向前后节点的引用,这增加了额外的内存开销。

线程安全性

  • ArrayList和LinkedList都不是线程安全的。如果在多线程环境下使用它们,需要手动进行同步处理或使用线程安全的替代品,如Collections.synchronizedList()CopyOnWriteArrayList

扩容机制

  • 当ArrayList的容量不足以容纳更多元素时,它会创建一个新的更大的数组,并将原数组中的元素复制到新数组中。这个过程可能会涉及大量的数据移动。而LinkedList则没有扩容的问题,因为它是基于链表的,可以动态地添加和删除节点。

ArrayList基于数组实现,其元素在内存中是连续存储的。这种连续性存储有助于节省空间,因为数组元素之间没有额外的指针或引用。然而,当ArrayList需要扩容时(即当添加元素导致当前数组容量不足时),它会创建一个新的更大的数组,并将原数组中的元素复制到新数组中。这个扩容过程可能会涉及到一定的内存开销。

LinkedList则基于链表实现,其每个节点包含数据和指向前后节点的引用。这种结构使得LinkedList在内存占用上相对较为分散。由于每个节点除了存储数据本身外,还需要额外的空间来存储指针或引用,因此LinkedList在存储相同数量的元素时,可能会占用更多的内存。此外,由于链表不是连续存储的,所以可能会存在内存碎片的问题,进一步增加了内存管理的复杂性。

然而,需要注意的是,内存占用的比较并不只是简单的“ArrayList比LinkedList更节省内存”或“LinkedList比ArrayList占用更多内存”。实际情况取决于多个因素,包括元素的数量、元素的大小、ArrayList的扩容频率以及具体应用场景等。在某些情况下,ArrayList可能由于减少了指针的开销而更节省内存;而在其他情况下,LinkedList可能由于更好的空间利用率而占用更少的内存。

关于ArrayList与LinkedList的选择

在实际应用中,选择ArrayList还是LinkedList并没有绝对的“哪种更好”的答案,而是取决于具体的应用场景和需求。下面是一些指导原则,可以帮助你做出选择:

访问模式

  • 如果你需要频繁地访问列表中的元素,特别是通过索引访问,那么ArrayList通常会是更好的选择。由于ArrayList是基于数组的,通过索引访问元素非常快速。
  • 相反,如果你主要是从头或尾开始遍历列表,或者进行插入和删除操作,那么LinkedList可能更合适。LinkedList的双向链表结构使得这些操作更加高效。

插入和删除操作

  • 如果你需要在列表的中间位置频繁地插入或删除元素,LinkedList的性能通常优于ArrayList。因为ArrayList在插入或删除元素时可能需要移动大量的元素以保持数组的连续性,而LinkedList只需要修改相关节点的指针指向。
  • 然而,如果你在列表的末尾添加元素,ArrayList的add方法通常比LinkedList更快,因为ArrayList的容量可以预先分配,而LinkedList则需要创建新的节点并更新指针。

内存占用

  • 在内存占用方面,ArrayList通常比LinkedList更紧凑,因为它在内存中是连续存储的。但是,当ArrayList需要扩容时,会涉及到创建新数组和复制元素的过程,这可能会增加临时的内存开销。
  • LinkedList由于每个节点都需要存储数据和指针,因此可能会占用更多的内存。然而,如果元素数量很大且ArrayList频繁扩容,那么LinkedList的内存占用可能会相对更稳定。

线程安全性

  • ArrayList和LinkedList都不是线程安全的。如果你在多线程环境下使用它们,需要手动进行同步处理或使用线程安全的替代品。因此,在选择数据结构时,还需要考虑线程安全性的需求。

其他考虑因素

  • 如果你正在处理大量数据且内存使用是一个关键问题,那么可能需要考虑使用更高效的数据结构或库,如Java中的ArrayDeque或第三方库提供的数据结构。
  • 如果你正在编写性能敏感的代码,那么最好进行基准测试以比较不同数据结构在实际应用中的性能表现。

综上所述,选择ArrayList还是LinkedList取决于你的具体需求和应用场景。在实际应用中,建议根据访问模式、插入和删除操作的频率、内存占用以及线程安全性等因素进行综合考虑,并可能需要进行基准测试来确定最佳的选择。

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

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

相关文章

1.2.3 利用注解配置类取代Spring配置文件

本实战将演示如何使用注解配置类取代Spring配置文件&#xff0c;实现基于注解的IoC容器的配置。 创建新包 在net.huawei.spring根包里创建day03子包。 拷贝类和接口 将day02子包里的类和接口拷贝到day03子包。 创建注解配置类 在day03子包里创建SpringConfig类。在该类上添加…

06 Php学习:字符串

PHP 中的字符串变量 在 PHP 中&#xff0c;字符串是一种常见的数据类型&#xff0c;用于存储文本数据。字符串变量可以包含字母、数字、符号等字符&#xff0c;并且可以进行各种操作和处理。以下是关于 PHP 中字符串变量的一些重要信息&#xff1a; 定义字符串变量&#xff1…

进制转换(2 8 10 16 String)

题目 public class Main {static String s "0123456789abcdef";//m 2 8 10 16public static int res(int n,int m) {StringBuffer sb new StringBuffer(); while(n!0) {sb.append(s.charAt(n%m));n/m;}//转换为对应进制之后String s sb.reverse().toString();ch…

达索PLM助力落地新型工业化

中国新时代新征程推进新型工业化 新型工业化&#xff0c;坚持以信息化带动工业化&#xff0c;以工业化促进信息化&#xff0c;就是科技含量高、经济效益好、资源消耗低、环境污染少、人力资源优势得到充分发挥的工业化道路。 新型工业化以高质量发展为目标。传统工业化注重规…

windows 之 redis非安装版,启动与初始化密码

1、下载redis 免安装版 2、解压后&#xff0c;启动服务 3、双击客服端 4、设置密码 config set requirepass root123456成功后&#xff0c;退出服务再次双击 5、登录 再次执行命名时已经没权限了 使用 auth password 登录 成功后&#xff0c;就可以了 auth root123456 …

简单爬虫(求过审核)

游客可以领取七天vip,愉快的开始爬取吧&#xff01; 首先从单章入手&#xff1a;逆天邪神漫画 第1话 两世为人 - 漫客栈 一章有很多图片&#xff0c;每一张图片都有自己的地址&#xff0c;目标就是找到一个包&#xff0c;包含这一章所有图片的地址。 打开开发者工具——刷新…

人脸识别业务(基于腾讯人脸识别接口)

使用腾讯云人脸识别接口&#xff0c;基于优图祖母模型。 一、准备工作 人脸识别账号 申请腾讯云服务器账号&#xff0c;生成自己的秘钥。记录秘钥和秘钥ID。 创建人员库 记下人员库id 在配置文件application.yml中添加配置。 plateocr:SecretId: 秘钥IDSecretKey: 秘钥ser…

全国水科技大会 免费征集《水环境治理减污降碳协同增效示范案例》

申报时间截止到2024年4月15日&#xff0c;请各单位抓紧申报&#xff0c;申报条件及申报表请联系&#xff1a;13718793867 围绕水环境治理减污降碳协同增效领域&#xff0c;以资源化、生态化和可持续化为导向&#xff0c;面向生态、流城、城市、农村、工业园区、电力、石化、钢…

高效实现红黑树范围查询:RB-ENUMERATE操作的设计与分析

高效实现红黑树范围查询&#xff1a;RB-ENUMERATE操作的设计与分析 一、RB-ENUMERATE操作的需求分析二、RB-ENUMERATE操作的设计思路三、RB-ENUMERATE操作的具体实现四、性能分析五、结论 在红黑树的广泛应用中&#xff0c;我们经常需要对树中的元素进行查询和操作。除了基本的…

堆放砖块-第12届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第47讲。 堆放砖块&#xf…

SuperMap GIS基础产品FAQ集锦(202403)

一、SuperMap GIS基础产品桌面GIS-FAQ集锦 问题1&#xff1a;【iDesktop】安装了idesktop 11i&#xff0c;现想进行插件开发&#xff0c;根据安装指南安装SuperMap.Tools.RegisterTemplate.exe&#xff0c;运行多次均失败 【问题原因】该脚本是之前老版本针对VS2010写的&…

亚信安慧AntDB:点亮数据灯塔

亚信安慧AntDB 是国产的分布式数据库&#xff0c;它具备快速发展的潜力。随着互联网技术的迅猛发展&#xff0c;大数据时代的到来&#xff0c;数据库的需求不断增长。在这样的背景下&#xff0c;国产分布式数据库正逐渐崭露头角&#xff0c;AntDB作为其中的重要代表&#xff0c…

MySQL学习笔记(数据类型, DDL, DML, DQL, DCL)

Learning note 1、前言2、数据类型2.1、数值类型2.2、字符串类型2.3、日期类型 3、DDL总览数据库/表切换数据库查看表内容创建数据库/表删除数据库/表添加字段删除字段表的重命名修改字段名&#xff08;以及对应的数据类型&#xff09; 4、DML往字段里写入具体内容修改字段内容…

Android输入框架

输入是一个操作系统的重要组成部分&#xff0c;没有输入&#xff0c;用户就无法向系统发送指令&#xff0c;也就没法完成人机交互。在Android系统中&#xff0c;输入系统是不可缺少的&#xff0c;下面简单介绍输入系统的整体框架&#xff0c;以下内容参考清华出版社出版的《And…

[react] useRef场景

1.记忆功能 -- 清定时器 先看和useState的差别 代码如下 不断地开启定时器 加上缓存就行,这样每次都是它 2.获取dom节点 当然!你可以直接在模板上面写函数! 函数变种也是可以的 你想获取整个组件也是没问题的 import React, { useRef, forwardRef } from "react";…

uniapp 2.0可视化开发工具高级事件使用技巧探索

摘要 随着移动应用市场的不断扩大和前端技术的飞速发展&#xff0c;开发者们对于快速、高效构建跨平台应用的需求日益增强。uniapp作为一款优秀的跨平台应用开发框架&#xff0c;凭借其强大的功能和易用的特性&#xff0c;赢得了广大开发者的青睐。在uniapp 2.0版本中&#xf…

ht1622不显示无反应问题解决

如果你正在写ht1622 驱动时&#xff0c;怎么看程序都没问题&#xff0c;抓取波形&#xff0c;示波器分析波形&#xff0c;如果都没有问题&#xff0c;那么很大可能是硬件问题&#xff0c;检测看看 ht1622 RD是不是接地了。 RD 低会进入读取模式&#xff0c;所以不用RD 请将RD悬…

基于Java+SpringBoot+Vue养老院管理系统(源码+文档+部署+讲解)

一.系统概述 随着信息时代的来临&#xff0c;过去的传统管理方式缺点逐渐暴露&#xff0c;对过去的传统管理方式的缺点进行分析&#xff0c;采取计算机方式构建养老院管理系统。本文通过课题背景、课题目的及意义相关技术&#xff0c;提出了一种社区活动、活动记录、床位信息、…

C++类与对象上(个人笔记)

类与对象 1.面向过程和面向对象初步认识2.类的定义3.类的访问限定符及封装3.1 访问限定符 4.封装5.类的实例化6.类对象6.1类对象的内存计算6.2内存对齐规则&#xff08;回顾&#xff09; 7.this指针7.1 this指针的特性 1.面向过程和面向对象初步认识 C语言是面向过程的&#x…

RabbitMQ安装延时插件

下载延迟插件 在 RabbitMQ 的 3.5.7 版本之后&#xff0c;提供了一个插件&#xff08;rabbitmq-delayed-message-exchange&#xff09;来实现延迟队列 &#xff0c;同时需保证 Erlang/OPT 版本为 18.0 之后。 我这里 MQ 的版本是 3.10.0 现在去 GitHub 上根据版本号下载插件 链…