Java集合相关的List、Set、Map基础知识

目录

一、集合介绍

二、List

三、Map

HashMap的数据结构

如何理解红黑树

四、set


一、集合介绍

在Java中,集合是一种用于存储对象的数据结构,它提供了一种更加灵活和强大的方式来处理和操作数据。Java集合框架提供了一系列接口和类,用于表示和操作不同类型的集合

图片来源:《面渣逆袭手册》V1.1

其中 Collection 是集合 List Set 的父接口,它主要有两个子接口:
        List :存储的元素有序,可重复。(相当于是个篮子,临时给你放数据用的
        Set :存储的元素无序,不可重复。(去重的List,放进去的东西如果一样,后面的会把前面的覆盖掉,得到的是个无重复值的列表
        Map 是另外的接口,是键值对映射结构的集合。(Map是个键值对,可以实现用a来搜b的作用,比如用用户的id搜用户的名称之类的操作

以下是Java中常见的集合:

  1. List(列表)

    • ArrayList:基于数组实现的动态数组,支持快速随机访问元素,但插入和删除操作效率较低。
    • LinkedList:基于链表实现的双向列表,插入和删除操作效率较高,但访问元素的效率较低。
    • Vector:与 ArrayList 类似,但是线程安全的,不推荐在新代码中使用。
    • Stack:基于 Vector 实现的栈,通常用于实现后进先出(LIFO)的数据结构。
  2. Set(集合)

    • HashSet:基于哈希表实现的集合,不保证元素的顺序。
    • TreeSet:基于红黑树实现的有序集合,可以按照自然顺序或者自定义顺序对元素进行排序。
    • LinkedHashSet:具有预期插入顺序的集合,内部使用链表维护元素的顺序。
  3. Map(映射)

    • HashMap:基于哈希表实现的映射,键值对无序。
    • TreeMap:基于红黑树实现的有序映射,键值对按照键的自然顺序或者自定义顺序进行排序。
    • LinkedHashMap:具有预期插入顺序的映射,内部使用链表维护键值对的顺序。
  4. Queue(队列)

    • PriorityQueue:基于堆实现的优先级队列,按照元素的优先级顺序进行排序。

此外,Java集合框架还包括一些接口和抽象类,如 CollectionMapIterator 等,它们提供了一组通用的操作和方法,可以方便地对集合进行操作和遍历。

二、List

在 Java 中,ArrayList 和 LinkedList 是两种常见的集合实现,它们有以下主要区别:

  1. 内存分配
    • ArrayList:使用连续的内存空间来存储元素。
    • LinkedList:使用链式存储结构,内存空间不连续,它们在空间占用上都有一些额外的消耗
    • ArrayList 是预先定义好的数组,可能会有空的内存空间,存在一定空间浪费
      LinkedList 每个节点,需要存储前驱和后继,所以每个节点会占用更多的空间
  2. 随机访问
    • ArrayList基于数组,所以它可以根据下标查找,支持快速的随机访问,通过索引可以快速获取元素。
    • LinkedList基于链表,所以它没法根据序号直接获取元素,在随机访问方面效率较低。
  3. 插入和删除
    • 多数情况下,ArrayList更利于查找,LinkedList更利于增删。
    • ArrayList 基于数组实现, get(int index) 可以直接通过数组下标获取,时间复杂度
      O(1) LinkedList 基于链表实现, get(int index) 需要遍历链表,时间复杂度是
      O(n) ;当然, get(E element) 这种查找,两种集合都需要遍历,时间复杂度都是
      O(n)
    • ArrayList增删如果是数组末尾的位置,直接插入或者删除就可以了,但是如果插
      入中间的位置,就需要把插入位置后的元素都向前或者向后移动,甚至还有可能
      触发扩容;双向链表的插入和删除只需要改变前驱节点、后继节点和插入节点的
      指向就行了,不需要移动元素。
    • 图片来源:《面渣逆袭手册》V1.1
  4. 内存占用
    • ArrayList:需要预先分配一定的内存空间,如果元素数量超过容量,需要进行扩容。
      基于数组的集合,数组的容量是在定义的时候确定的,如果数组满了,
      再插入,就会数组溢出。所以在插入时候,会先检查是否需要扩容,如果当前容量
      +1 超过数组长度,就会进行扩容。
    • ArrayList的扩容是创建一个1.5的新数组,然后把原数组的值拷贝过去。
    • LinkedList:不需要预先分配固定的内存空间。
  5. 遍历方式
    • ArrayList:可以通过索引或迭代器进行遍历。
    • LinkedList:还可以通过指针依次访问元素。
      示例代码如下:
    • import java.util.ArrayList;
      import java.util.LinkedList;
      import java.util.List;
      
      public class CollectionExample {
      
          public static void main(String[] args) {
      
              // 使用 ArrayList
              List<String> arrayList = new ArrayList<>();
              arrayList.add("Apple");
              arrayList.add("Banana");
              arrayList.add("Orange");
      
              System.out.println("使用 ArrayList 遍历:");
              for (String item : arrayList) {
                  System.out.println(item);
              }
      
              // 使用 LinkedList
              List<String> linkedList = new LinkedList<>();
              linkedList.add("Apple");
              linkedList.add("Banana");
              linkedList.add("Orange");
      
              System.out.println("\n 使用 LinkedList 遍历:");
              for (String item : linkedList) {
                  System.out.println(item);
              }
          }
      }

三、Map

在 Java 中,常见的 Map 实现有 HashMap 和 TreeMap 。

HashMap 基于哈希表实现,它的数据结构如下:

  • 存储键值对。
  • 通过哈希函数计算键的哈希值,以确定元素在哈希表中的存储位置。

TreeMap 基于红黑树实现,它的数据结构如下:

  • 按照键的自然顺序进行排序。
  • 提供有序的键值对访问。

HashMap的数据结构

JDK1.8 的数据结构是 数组 + 链表 + 红黑树

数据结构示意图如下:

图片来源:《面渣逆袭手册》V1.1

其中,桶数组是用来存储数据元素,链表是用来解决冲突, 红黑树 是为了提高查询
的效率。
数据元素通过映射关系,也就是散列函数,映射到桶数组对应索引的位置
如果发生冲突,从冲突的位置拉一个链表,插入冲突的元素
如果链表长度  > 8 &  数组大小  >= 64  ,链表转为红黑树
如果红黑树节点个数  < 6 ,转为链表

哈希表的基本原理是通过哈希函数将键映射到特定的存储位置,以实现快速的插入、查找和删除操作。


哈希函数用于计算键的哈希值,并根据哈希值确定元素在哈希表中的存储位置。哈希表通常包含以下组件:

  1. 数组:用于存储元素。
  2. 哈希函数:将键转换为数组的索引。
  3. 冲突处理机制:处理不同键可能映射到相同索引的冲突。

在插入元素时,通过哈希函数计算键的哈希值,确定存储位置。如果该位置为空,则直接插入元素;如果存在冲突,使用冲突处理机制解决。

在查找元素时,同样通过哈希函数计算哈希值,找到对应的位置进行查找。

哈希表的优点包括:

  1. 快速的插入、查找和删除操作。
  2. 不需要按照特定顺序存储元素。

如何理解红黑树

红黑树本质上是一种二叉查找树,为了保持平衡,它又在二叉查找树的基础上增加了一些规则:
  1. 颜色规则:每个节点要么是红色,要么是黑色
  2. 特性规则:
    • 根节点是黑色的。
    • 如果一个节点是红色的,那么它的子节点必须是黑色的。
    • 从每个叶子节点到根节点的所有路径上,黑色节点的数量相同。
      在进行插入或删除操作时,红黑树会通过一系列的旋转和颜色调整来保持这些规则,以确保树的平衡性。

图片来源:《面渣逆袭手册》V1.1

旋转操作包括左旋和右旋,用于调整树的结构。

红黑树有两种方式保持平衡: 旋转 染色 通过保持红黑树的平衡性,可以提高搜索、插入和删除操作的效率,避免出现最坏情况下的线性搜索。

有关HashMap的知识点非常多,这里不做详述,后面会单独写一篇有关HashMap的相关内容。

哈希表在以下场景中比较适用:

  1. 快速查找:当需要快速查找数据时,哈希表可以提供高效的查找性能。
  2. 存储和检索数据:适用于需要频繁地插入、删除和查找数据的场景。
  3. 缓存:可以用于缓存数据,以提高系统的性能。
  4. 统计频率:用于统计元素的出现频率。
  5. 数据去重:去除重复的数据。
  6. 关联数据:建立键值对的关联。
    例如,在以下场景中可能会使用哈希表:
  7. 数据库索引:加速数据的查询。
  8. 缓存系统:提高数据的访问速度。
  9. 网页搜索引擎:快速检索和索引网页。
  10. 数据处理和分析:高效地处理大量数据。

四、set

HashSet 是 Java 中的一个集合类,它不允许存储重复的元素。HashSet 底层就是基于 HashMap 实现的。( HashSet 的源码⾮常⾮常少,因为除了 clone() 、 writeObject() 、 readObject() 是 HashSet⾃⼰不得不实现之外,其他⽅法都是直接调⽤ HashMap 中的⽅法。

HashSet的add方法,直接调用HashMap的put方法,将添加的元素作为key,new一个 Object作为value,直接调用HashMap的put方法,它会根据返回值是否为空来判断是否插入元素成功。

以下是 HashSet 的一些特点:

  1. 无序性:元素的存储顺序是无序的。
  2. 不允许重复元素:确保每个元素在集合中唯一。
  3. 基于哈希表实现:提供快速的插入、查找和删除操作。

参考

《面渣逆袭手册》V1.1.pdf

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

leetcode1143. 最长公共子序列(ACM模式解法)

题目描述 给你一个序列X和另一个序列Z&#xff0c;当Z中的所有元素都在X中存在&#xff0c;并且在X中的下标顺序是严格递增的&#xff0c;那么就把Z叫做X的子序列。 例如&#xff1a;Z是序列X的一个子序列&#xff0c;Z中的元素在X中的下标序列为<1,2,4,6>。 现给你两个…

界面组件DevExpress Blazor UI v23.2 - 支持.NET 8、全新的项目模版

DevExpress Blazor UI组件使用了C#为Blazor Server和Blazor WebAssembly创建高影响力的用户体验&#xff0c;这个UI自建库提供了一套全面的原生Blazor UI组件&#xff08;包括Pivot Grid、调度程序、图表、数据编辑器和报表等&#xff09;。 DevExpress Blazor控件目前已经升级…

4/26发布发布:缺了好几次的作业,矩形法+二分法求下面方程根+顺序查找n+程序填空,补一下还有八九没做,炸8412 字不是干的,哈哈哈

OK了发布 你说的对&#xff0c;但是釜山行里逃过了六节车厢的丧尸&#xff0c;却逃不过一节车厢的人心&#xff0c;这说明了什么&#xff1f;说明一节更比六节强&#xff0c;王中王&#xff0c;火腿肠&#xff0c;果冻我要喜之郎&#xff0c;上课要听鹏哥讲&#xff01; 目录…

合合信息:acge_text_embedding 文本向量化模型登顶 C-MTEB 中文榜单

近期&#xff0c;合合信息的 acge_text_embedding 文本向量化模型在最近的比赛中获得了 MTEB 中文榜单&#xff08;C-MTEB&#xff09;榜首&#xff01;C-MTEB 作为中文文本向量性能的评测标准&#xff0c;以其全面性和权威性在业内享有盛誉值得关注。接下来让我们仔细分析一下…

SL1581 耐压30V蓝牙音响应用 24降5V 12降5V 外围简单

SL1581蓝牙音响应用方案是一种高效、稳定的电源管理方案&#xff0c;专为蓝牙音响设备设计。该方案采用耐压30V降压5V的设计&#xff0c;能够有效地将高电压降至适合蓝牙音响设备工作的低电压&#xff0c;保证设备的稳定运行。同时&#xff0c;外围电路设计简单&#xff0c;方便…

分布式与一致性协议之CAP(五)

CAP 理论 如何使用BASE理论 以InfluxDB系统中DATA节点的集群实现为例。DATA节点的核心功能是读和写&#xff0c;所以基本可用是指读和写的基本可用。我们可以通过分片和多副本实现读和写的基本可用。也就是说&#xff0c;将同一业务的数据先分片&#xff0c;再以多份副本的形…

C语言基础知识笔记——万字学习记录

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本文主要参考浙大翁恺老师的C语言讲解以及其他博主的C语言学习笔记&#xff0c;进而梳理C语言的基础知识&#xff0c;为后续系统性学习数据结构和其他语言等知识夯实一定的基础。&#xff08;其他博主学习笔记的链接包括&#x…

【运维】Git 分支管理

一般来讲&#xff0c;系统代码需要经过研发、测试、生产三种环境。那么在Git上如何管理分支&#xff0c;才不会乱&#xff1f;在线上生产环境有问题时有条不紊的解决。 经过发展&#xff0c;有一个Git Flow原理可帮助解决。设置以下几种分支。 master——production生产环境。…

Fusion360导入STL和OBJ文件转化为实体文件自由编辑

Fusion360导入STL和OBJ文件转化为实体文件自由编辑 1.概述 在模型网站上下载的3D打印文件通常是STL和OBJ格式文件&#xff0c;该类型文件都是网格类型的文件&#xff0c;Fusion360只可以对实体文件进行编辑。因此不能对他们直接修改&#xff0c;需要导入文件将他们转为实体文…

Linux多进程(五) 进程池 C++实现

一、进程池的概念 1.1、什么是进程池 进程池是一种并发编程模式&#xff0c;用于管理和重用多个处理任务的进程。它通常用于需要频繁创建和销毁进程的情况&#xff0c;以避免因此产生的开销。 进程池的优点包括&#xff1a; 减少进程创建销毁的开销&#xff1a;避免频繁创建和…

笔记:编写程序,分别采用面向对象和 pyplot 快捷函数的方式绘制正弦曲线 和余弦曲线。 提示:使用 sin()或 cos()函数生成正弦值或余弦值。

文章目录 前言一、面向对象和 pyplot 快捷函数的方式是什么&#xff1f;二、编写代码面向对象的方法&#xff1a;使用 pyplot 快捷函数的方法&#xff1a; 总结 前言 本文将探讨如何使用编程语言编写程序&#xff0c;通过两种不同的方法绘制正弦曲线和余弦曲线。我们将分别采用…

备考2024年小学生古诗文大会:做做10道历年真题和知识点(持续)

根据往年的安排&#xff0c;2024年上海市小学生古诗文大会预计还有一个月就将启动。我们继续来随机看10道往年的上海小学生古诗文大会真题&#xff0c;这些题目来自我去重、合并后的1700在线题库&#xff0c;每道题我都提供了参考答案和独家解析。 根据往期的经验&#xff0c;只…

【网络原理】TCP协议的相关机制(确认应答、超时重传)

系列文章目录 【网络通信基础】网络中的常见基本概念 【网络编程】Java网络编程中的基本概念及实现UDP、TCP客户端服务器程序&#xff08;万字博文&#xff09; 【网络原理】UDP协议的报文结构 及 校验和字段的错误检测机制&#xff08;CRC算法、MD5算法&#xff09; 文章目…

uniapp制作分页查询功能

效果 代码 标签中 <uni-pagination change"pageChanged" :current"pageIndex" :pageSize"pageSize" :total"pageTotle" class"pagination" /> data中 pageIndex: 1, //分页器页码 pageSize: 10, //分页器每页显示…

第72天:漏洞发现-Web框架中间件联动GobyAfrogXrayAwvsVulmap

案例一&#xff1a;某 APP-Web 扫描-常规&联动-Burp&Awvs&Xray Acunetix 一款商业的 Web 漏洞扫描程序&#xff0c;它可以检查 Web 应用程序中的漏洞&#xff0c;如 SQL 注入、跨站脚本攻击、身份验证页上的弱口令长度等。它拥有一个操作方便的图形用户界 面&#…

基于yolov5实时实例分割

是一个结合了最新技术进展&#xff08;State-of-the-Art, SOTA&#xff09;的实时实例分割项目&#xff0c;基于著名的YOLOv5目标检测架构&#xff0c;并对其进行扩展以实现对图像中每个对象实例的精确像素级分割。以下是该项目的中文介绍&#xff1a; YOLOv5&#xff1a; YOL…

数据结构八:线性表之循环队列的设计

上篇博客&#xff0c;学习了栈&#xff0c;我们可以知道他也是一种线性表&#xff0c;遵从先进后出的原则&#xff0c;在本节&#xff0c;我们进一步学习另一种线性表—队列。就像饭堂里排队打饭的的队伍&#xff0c;作为一种先进先出的线性表&#xff0c;他又有哪些特别之处呢…

实现Spring底层机制(二)

文章目录 阶段2—封装bean定义信息到Map1.代码框架图2.代码实现1.文件目录2.新增注解Scope存储单例或多例信息Scope.java3.修改MonsterService.java指定多例注解4.新增bean定义对象存储bean定义信息BeanDefinition.java5.修改pom.xml增加依赖6.修改容器实现bean定义信息扫描Sun…

C语言|关于C语言变量的作用域、链接、存储期及相关知识(C多文件编程基础)

文章目录 作用域块作用域(block scope)函数作用域(function scope)函数原型作用域(function prototype scope)文件作用域(file scope)翻译单元和文件(作用域&#xff09; 链接(linkage)存储期(Storege Duration)静态存储期(static storage duration)线程存储期(thread storage …

kafka启动报错(kafka.common.InconsistentClusterIdException)

文章目录 前言kafka启动报错(kafka.common.InconsistentClusterIdException)1. 查找日志2. 定位问题/解决 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不…
最新文章