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

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.rhkb.cn/news/303558.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

亚马逊运营必看!如何运用自养号测评获得买家评论转销量?

作为亚马逊卖家&#xff0c;相信大家对亚马逊的产品星级评分 (Rating) 都不陌生&#xff0c;这几颗亮眼的星星&#xff0c;不仅可以让你的Listing脱颖而出&#xff0c;获得足够多、足够高的产品评分&#xff0c;也是促使消费者下单的重要因素之一。 那么&#xff0c;亚马逊运营…

3D可视化技术亮相高铁站,引领智慧出行新潮流

在科技飞速发展的今天&#xff0c;我们的生活正经历着前所未有的变革。高铁站作为现代交通的重要枢纽&#xff0c;也在不断地创新和进步。 3D可视化技术通过三维立体的方式&#xff0c;将高铁站内部和外部的结构、设施、流线等以更加直观、生动的形式呈现出来。乘客们只需通过手…

全国高等学校sql

教育部颁发的最新高等学校名单&#xff0c;sql已整理好(按照省份树形结构)&#xff0c;是mysql8版本的 全国高等学校:预览地址&#xff1a;https://kdocs.cn/l/ckaFzCWMV1jn sql下载地址&#xff1a; https://pan.imgbed.link/file/22581

mac/win使用pyinstaller打包app/exe文件,活着执行脚本,双击运行

&#x1f338; 踩坑记录 python环境最好使用虚拟环境&#xff0c;推荐使用conda管理&#xff0c;并且若本地有python环境&#xff0c;不要使用和 本地环境版本 相同的虚拟环境 这里踩坑较多&#xff0c;已经记不清楚注意点 虚拟环境python版本不要和本地环境一样 mac/win只能…

匿名信一封来信一封云来信表白祝福道歉短信H5公众号,小程序系统搭建(搭建赠送人工传话系统+主机管理面板)

“一封来信”是最近某音上爆火的一个活动话题&#xff0c;可以通过H5网站&#xff0c;编辑自己想要对某人说的话或者祝福&#xff0c;网站会把您想说的发给您预留的号码&#xff0c;可以特定时间&#xff0c;特定话题。 最近的兴起是给朋友或暗恋的人发送新年祝福&#xff0c;…

Leetcode算法训练日记 | day21

一、二叉搜索树的最小绝对差 1.题目 Leetcode&#xff1a;第 530 题 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的绝对值。 示例 1&#xff1a; 输入&#xff1a;root [4,2,…

『大模型笔记』LLMs入门:从头理解与编码LLM的自注意力机制

LLMs入门&#xff1a;从头理解与编码LLM的自注意力机制 这里直接引用我语雀上的的文章&#xff1a;《从头理解与编码LLM的自注意力机制》

python第四次作业

1、找出10000以内能被5或6整除&#xff0c;但不能被两者同时整除的数&#xff08;函数&#xff09; def func():for i in range(10001):if (i % 5 0 or i % 6 0) and i % 30 ! 0:print(i,end " ")func() 2、写一个方法&#xff0c;计算列表所有偶数下标元素的…

AWVS/Acunetix Premium V24.3.2403高级版漏洞扫描器

前言 Acunetix Premium 是一种 Web 应用程序安全解决方案&#xff0c;用于管理多个网站、Web 应用程序和 API 的安全。集成功能允许您自动化 DevOps 和问题管理基础架构。 Acunetix Premium&#xff1a;全面的 Web 应用程序安全解决方案 Web 应用程序对于企业和组织与客户、…

优先级队列

优先级队列的基本使用 模拟实现上面的接口函数&#xff0c;优先级队列不是队列&#xff0c;而是类似一个堆一样的东西&#xff0c;我们先来试试它的接口函数是怎么个样子的。 需要包含的头文件是queue。 #include<iostream> #include<queue> using namespace std;…

Qt Creator 新建项目

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;QT❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、使用 Qt Creator 新建项目 1、新建项目 2、选择项目模板 3、选择项目路径 4、选择构建系统 5…

基于达梦数据库开发-python篇

文章目录 前言一、搭建demo前提初始化简单demo 二、可能出现的异常情况DistutilsSetupErrorNo module named dmPythonlist报错 总结 前言 出于信创的考虑&#xff0c;近年来基于国产数据库达梦的应用开发逐渐变多。本文将介绍在windows环境下基于DM8版本的python的简单开发使用…

PaddleVideo:onnx模型导出

本文节介绍 PP-TSM 模型如何转化为 ONNX 模型&#xff0c;并基于 ONNX 引擎预测。 1&#xff1a;环境准备 安装 Paddle2ONNX python -m pip install paddle2onnx 安装 ONNXRuntime # 建议安装 1.9.0 版本&#xff0c;可根据环境更换版本号 python -m pip install onnxrunti…

windows10/11重启电脑自动开启热点

windows10/11重启电脑自动开启热点 一、前言二、要做的所有步骤及原理2.1 下载文件2.2 打开系统运行PS1文件限制2.3 给.bat文件创建桌面快捷方式2.4 关闭热点&#xff0c;双击快捷方式&#xff0c;查看热点是否成功开启2.5 将快捷方式加入开启自启 一、前言 有某种场景&#x…

华为数通配置旁挂二层组网直接转发实验

配置旁挂二层组网直接转发示例 组网图形 组网需求 AC组网方式&#xff1a;旁挂二层组网。DHCP部署方式&#xff1a; AC作为DHCP服务器为AP分配IP地址。汇聚交换机SwitchB作为DHCP服务器为STA分配IP地址。业务数据转发方式&#xff1a;直接转发。 数据规划 表1 AC数据规划表 …

【C++第二阶段】文件操作

以下内容仅为当前认识&#xff0c;可能有不足之处&#xff0c;欢迎讨论&#xff01; 文章目录 文件操作文件写入流程简单的demo写操作 文件读流程二进制写文件二进制读文件 文件操作 文件写入流程 写文件包括以下几个步骤 1.包含头文件 2.创建流对象 3.打开文件&#xff0…

41-软件部署实战(中):IAM系统生产环境部署实战

下面四个步骤来部署IAM应用&#xff1a; 在服务器上部署IAM应用中的服务。配置Nginx&#xff0c;实现反向代理功能。通过反向代理&#xff0c;我们可以通过Nginx来访问部署在内网的IAM服务。配置Nginx&#xff0c;实现负载均衡功能。通过负载均衡&#xff0c;我们可以实现服务…

合并两个单链表

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 但行前路&#xff0c;不负韶华&#…

【教学类-50-05】20240410“数一数”4类图片添加“难度星号”

作品展示 背景需求 前期已经制作了四类“数一数”学具&#xff0c;具体样式如下&#xff1a; 1、难度1.0 【教学类-50-01】20240407“数一数”图片样式01&#xff1a;图形与边框不重合&#xff0c;图形和其他图形不相交-CSDN博客文章浏览阅读293次&#xff0c;点赞20次&…

STL容器之unordered_set类

文章目录 STL容器之unordered_set类1、unordered系列关联式容器2、unordered_set2.1、unordered_set介绍2.2、unordered_set的使用2.2.1、unordered_set的常见构造2.2.2、unordered_set的迭代器2.2.3、unordered_set的容量2.2.4、unordered_set的增删查2.2.5、unordered_set的桶…