Java的集合框架总结

Map接口和Collection接口是所有集合框架的父接口:

  1. Collection接口的子接口包括:Set接口和List接口

  1. Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等

  1. Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等

  1. List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等

List接口及其实现

ArrayList

  • 基于动态数组实现

  • 允许快速随机访问元素

  • 插入和删除操作可能需要移动其他元素,因此在中间位置插入和删除的时间复杂度为O(n)

  • 非同步,不是线程安全的,可以使用使用Collections.synchronizedList(new ArrayList<>()) 创建一个同步的 ArrayList

LinkedList
  • 基于双向链表实现

  • 允许快速插入删除元素

  • 不能快速随机访问,访问元素的时间复杂度为O(n)

  • 非同步,不是线程安全的。可以使用 Collections.synchronizedList(new LinkedList<>()) 创建一个同步的 LinkedList

  • 可以用做队列或双向队列

    依赖于两个节点(一个头节点一个尾节点)

    常用方法

    添加

    add(E e):在链表后添加一个元素; 通用方法 addFirst(E e):在链表头部插入一个元素; 特有方法 addLast(E e):在链表尾部添加一个元素; 特有方法

    删除

    removeFirst(E e):删除头,获取元素并删除; 特有方法 removeLast(E e):删除尾; 特有方法

    查看

    getFirst():获取第一个元素; 特有方法 getLast():获取最后一个元素; 特有方法

Stack
  • 基于Vector实现,代表了后进先出()

  • 是同步的,是线程安全的

  • push入栈、peek查看栈顶元素、pop出栈、empty是否为空、size()获取数目

Vector
  • 基于动态数组实现,类似于ArrayList

  • 同步的,是线程安全的

  • 是需要线程安全的动态数组是使用,但是通常使用ArrayListCollections.syschronizedList来代替

Set接口及其实现类

set其实一直在用map那一套

 public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable {private transient HashMap<E,Object> map;private static final Object PRESENT = new Object();​public HashSet() {map = new HashMap<>();}​public boolean add(E e) {return map.put(e, PRESENT) == null;}​// Other methods delegate to the underlying map}​
HashSet
  • 元素存储HashSet 将元素添加到底层的 HashMap 中,键是元素的哈希码,值是一个占位符对象。HashSet的实现是基于HashMap的,他使用HashMap来存储元素,在HashSet中,元素被当作HashMap的键,而HashMap的值则是一个固定的占位符,通常是 PRESENT 对象(一个静态内部类对象)。这样做是为了节省空间,因为 HashSet 只关心元素的唯一性,不需要存储额外的值。

  • 去重HashSet 使用了 HashMap 键的唯一性来确保 HashSet 中不会有重复的元素。

  • 不保证集合的迭代顺序,顺序可能会随时间变化。

  • 方法委派HashSet 的许多方法(如 addremovecontains 等)都是通过调用底层 HashMap 的对应方法来实现的。

  • 性能:由于 HashSet 是基于 HashMap 实现的,所以其性能与 HashMap 类似,添加、删除和查找操作的平均时间复杂度为 O(1)。

  • 允许存储null值。

LinkedHashSet

LinkedHashSetHashSet 的一个子类,它继承了 HashSet 的特性,并且保持了元素的插入顺序。下面是关于 LinkedHashSet 的一些关键点:

  • 继承自HashSet并且使用链表维护元素的插入顺序

  • 保证迭代顺序与插入顺序一致

  • 允许存储null值。

  • 插入、删除、和查找操作的时间复杂度为O(1)。

实现细节

  • 当你向 LinkedHashSet 添加元素时,它会使用 LinkedHashMap 来存储元素。

  • 每个元素被当作 LinkedHashMap 的键,值则是一个固定的占位符对象。

  • LinkedHashSet 通过委派 LinkedHashMap 来实现其 addremovecontains 等方法。

TreeSet

TreeSet 是 Java 中实现 SortedSet 接口的一个集合类,它基于 TreeMap 实现,并且元素是按照自然顺序(或通过提供的比较器)排序的。以下是 TreeSet 的一些关键点:

  • 基于红黑树(自平衡二叉搜索树)实现

  • 元素是有序的,元素按照自然顺序(或通过Comparator指定的顺序)排

  • 不允许存储null值(会抛出NullPointerException

  • 插入、删除、和查找操作的时间复杂度为O(log n)。

Map接口及其实现类
HashMap

  • 基于哈希表实现,调用put方法值,首先将k,v封装到Node对象中,然后底层会调用k的hashCode()方法得到hash值。根据这个值来决定到底该插入数组下标的哪个位置,如果有两个值的哈希值一样,就会调用equals方法进行比较,如果哈希值一样但是不相等,就会形成链表插入 ,如果相等那么相等的这个节点的value将会被覆盖。如果没有元素占用位置,就直接放入即可。(通过数组加链表形式)

  • 在Java8对hashmap进行了优化,如果相同哈希值,链表的长度超过8,就从链表转换成红黑树。第一次添加元素的时候,默认初期长度为16,当往map中继续添加元素的时候,通过hash值跟数组长度取“与”来决定放在数组的哪个位置,如果出现放在同一个位置的时候,优先以链表的形式存放,在同一个位置的个数又达到了8个(代码是>=7,从0开始,及第8个开始判断是否转化成红黑树),如果数组的长度还小于64的时候,则会扩容数组。如果数组的长度大于等于64的话,才会将该节点的链表转换成树。在扩容完成之后,如果某个节点的是树,同时现在该节点的个数又小于等于6个了,则会将该树转为链表(只有当数据量大于64才会有红黑树+链表)

  • HashMap内部结构是数组(Node[] table)和链表结合组成的复合结构,数组被分成一个个桶(bucket)或槽,通过哈希值决定键值对在这个数组的寻址;哈希值相同的键值对,则以链表形式存储。当链表大小超过阈值(TREEIFY_THRESHOLD = 8)时,链表就会被改造成树形结构。(查询效率变高)

  • Java8不再像Java7中那样需要满足两个条件,Java8中扩容只需要满足一个条件:当前存放新值(注意不是替换已有元素位置时)的时候已有元素的个数大于等于阈值(已有元素等于阈值,下一个存放后必然触发扩容机制)且扩容发生在存放后,即是数据存放后(先存放后扩容),判断当前存入对象的个数,如果大于阈值则进行扩容。

  • 允许存储null键和null值。

  • 插入、删除、和查找操作的时间复杂度为O(1)。

  • 非同步,不是线程安全的。

LinkedHashMap

  • 通过hashmap跟双向链表实现,可以确保按照插入顺序迭代链表

  • 遍历性能: 与普通的HashMap相比,在迭代LinkedHashMap时,性能更加稳定。因为它不需要遍历整个桶,而是按照链表顺序遍历元素。

  • 实现方式: 在内部实现上,LinkedHashMap在每个条目中保留了前一个和后一个条目的引用,以实现双向链表。这使得在插入、删除和遍历元素时的性能表现良好。

TreeMap

  • 基于红黑树实现

  • 键按照自然顺序(或通过Comparator指定的顺序)排序。

  • 不允许存储Null键

  • 插入、删除、和查找操作的时间复杂度为O(log n)。

Hashtable
  • 也是使用哈希表还有链表实现

  • 同步的,是线程安全的。

  • 不允许存储null键和null值。

  • 插入、删除、和查找操作的时间复杂度为O(1)。

Properties
  • 继承自Hashtable,表示一个持久化的属性集。

  • 每个键及其对应值都是一个字符串。

  • 常用于读取和写入配置文件。

ConcurrentHashMap
  • 不允许存储null键和null值。

  • 插入、删除、和查找操作的时间复杂度为O(1)。

  • 在多线程环境下,使用HashMap进行put操作时存在丢失数据的情况,为了避免这种bug的隐患,强烈建议使用ConcurrentHashMap代替HashMap。

  • HashTable是一个线程安全的类,它使用synchronized来锁住整张Hash表来实现线程安全,即每次锁住整张表让线程独占,相当于所有线程进行读写时都去竞争一把锁,导致效率非常低下。ConcurrentHashMap可以做到读取数据不加锁,并且其内部的结构可以让其在进行写操作的时候能够将锁的粒度保持地尽量地小,允许多个修改操作并发进行,其关键在于使用了锁分段技术。它使用了多个锁来控制对hash表的不同部分进行的修改。

分段锁(Segment Locking)机制

早期版本的ConcurrentHashMap(Java 7及之前)使用分段锁机制,具体如下:

  • ConcurrentHashMap内部将整个哈希表分为多个段(Segment),每个段都是一个独立的哈希表,并拥有自己的锁。

  • 这种机制允许多个线程同时访问不同段的元素,从而提高并发度。

  • ConcurrentHashMap 为了提高本身的并发能力,在内部采用了一个叫做 Segment 的结构,一个 Segment 其实就是一个类 Hash Table 的结构,Segment 内部维护了一个链表数组,我们用下面这一幅图来看下 ConcurrentHashMap 的内部结构,从下面的结构我们可以了解到,ConcurrentHashMap 定位一个元素的过程需要进行两次Hash操作,第一次 Hash 定位到 Segment,第二次 Hash 定位到元素所在的链表的头部,因此,这一种结构的带来的副作用是 Hash 的过程要比普通的 HashMap 要长,但是带来的好处是写操作的时候可以只对元素所在的 Segment 进行操作即可,不会影响到其他的 Segment,这样,在最理想的情况下,ConcurrentHashMap 可以最高同时支持 Segment 数量大小的写操作(刚好这些写操作都非常平均地分布在所有的 Segment上),所以,通过这一种结构,ConcurrentHashMap 的并发能力可以大大的提高。

CAS操作和分段锁

在Java 8中,ConcurrentHashMap使用了一种新的机制,结合了CAS(Compare-And-Swap)操作和细粒度的分段锁。

  • 使用CAS操作来保证对单个节点的原子性操作,减少锁的使用。

  • 在插入、删除和更新操作中,如果CAS操作失败(即另一个线程同时修改了相同的位置),则退而使用锁进行操作。

  • 在Java 8中,ConcurrentHashMap取消了分段锁的概念,直接在哈希桶(bucket)级别进行锁定,使用CAS操作和synchronized块来保证并发安全。这使得数据结构更加简单,且操作更加直观。

  • 为了优化哈希冲突情况下的查找性能,Java 8引入了红黑树。当链表的长度超过一定阈值(默认是8)时,链表会转换为红黑树。这样,在高冲突情况下,查找操作的时间复杂度从O(n)降到了O(log n),极大地提高了性能。

  • CAS 操作通过比较当前值与预期值,如果两者相等则更新为新值,否则重试该操作。

数据结构

ConcurrentHashMap在Java 8中的内部数据结构有以下几个关键组成部分:

  • 数组(Node<K,V>[] table):哈希表的核心数组,存储链表或红黑树的头节点。

  • 链表和红黑树:数组中的每个桶(bucket)最初是一个链表。当链表长度超过阈值(8)时,链表会转换为红黑树,以提高查询效率。

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

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

相关文章

大数据实训项目(小麦种子)-03、大数据环境Hadoop、Mapreduce、Hive、Hbase、HDFS搭建服务及调试

文章目录 前言一、Linux系统Centos7安装配置JDK8二、Linxu系统Centos7中搭建Hadoop3.1.0服务下载地址服务1&#xff1a;详细步骤&#xff08;初始化与启动dfs服务&#xff09;详细步骤配置环境变量 服务2&#xff1a;Hadoop(YARN)环境搭建 三、Linux系统搭建Hive3.1.2服务前提条…

记录AE快捷键(持续补充中。。。)

记录AE快捷键 快捷键常用快捷键图层快捷键工具栏图层与属性常用指令视图菜单时间轴常规快捷键项目首选项功能摄像机操作 常用操作导入AI/PS工程文件加选一个关键参数快速回到上下一帧隐藏/显示图层关键帧拉长缩短关键帧按着鼠标左键不松手&#xff0c;在秒表那一列往下移动会都…

深度学习(PyTorch)批注理解,建议边学可以边看这个笔记

前言 动手学习深度学习&#xff0c;内容丰富&#xff0c;但是对于初学者有很多晦涩难懂的地方&#xff0c;我将日常更新这篇文章以截图的形式&#xff0c;每天高强度学习四五个小时&#xff0c;精力缺乏&#xff0c;我认为&#xff0c;如果想学习这个深度学习&#xff0c;你需…

ubuntu vnc

如何在Ubuntu 18.04安装VNC | myfreax sudo apt install xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils sudo apt install tigervnc-standalone-server tigervnc-common vncserver sudo apt install xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils sudo apt ins…

5.数据仓库与数据挖掘期末复习

ETL的含义Extract 、 Transformation、Load。ODS的全称Operational Data Store。 DW全称 Data WarehourseDM全称是Data Mart数据仓库数据抽取时所用到技术是增量、全量、定时、调度STAGE层作用是提供业务系统数据文件的临时存储ODS层作用ods提供业务系统细节数据长期沉淀MID层…

实用软件下载:BetterZip 5最新安装包及详细安装教程

BetterZip是一款功能强大的Mac解/压缩软件&#xff0c;可以满足用户对文件压缩、解压、加密和保护等方面的需求。以下是关于BetterZip软件的主要功能、特点和使用方法的详细介绍&#xff0c;以及对其用户友好度、稳定性和安全性的评价。 安 装 包 获 取 地 址: BetterZip 5-安…

057、PyCharm 运行代码报错:Error Please select a valid Python interpreter

当我们在PyCharm运行代码时&#xff0c;提示如下图错误&#xff1a; 那么问题通常是由于PyCharm未正确配置Python解释器引起的。 我们只需按以下步骤重新配置Python解释器即可&#xff1a; 打开PyCharm设置&#xff1a; 在菜单栏中的点击 “File” -> “Settings”&#xf…

选择性语言建模:下一代语言模型训练方法

在人工智能领域&#xff0c;语言模型的预训练方法一直是研究的热点。传统的语言模型预训练方法普遍采用一种均匀的策略&#xff0c;即对所有训练数据中的下一个词进行预测&#xff0c;这种方法被称为因果语言建模&#xff08;Causal Language Modeling, CLM&#xff09;。虽然C…

Nginx配置详细解释:(6)实现反向代理服务器,动静分离,负载均衡

目录 单台反向代理 proxy_pass后面加不加/的问题&#xff1a; 反向代理动静分离 反向代理负载均衡 作为代理服务器是当客户端访问代理服务器时&#xff0c;代理服务器代理客户端去访问真实web服务器。proxy_pass; 用来设置将客户端请求转发给的后端服务器的主机。 需要模块…

Android入门第69天-AndroidStudio中的Gradle使用国内镜像最强教程

背景 AndroidStudio默认连接的是dl.google的gadle仓库。 每次重新build时: 下载速度慢;等待了半天总时build faild;build到一半connection timeout;即使使用了魔法也难以一次build好;这严重影响了我们的学习、开发效率。 当前网络上的使用国内镜像的教程不全 网上的教程…

C++100行超简单系统

非常好用&#xff0c;小白也可以自己修改 先来看图片&#xff1a; 用法附在代码里了&#xff01; #include <bits/stdc.h> #include <windows.h>using namespace std;struct users {string name;string num; bool f; } u[10000];int now_users 0; /*当前用户数*…

20240615在WIN11下的串口调试助手的下载安装以及使用

20240615在WIN11下的串口调试助手的下载安装以及使用 2024/6/15 18:06 百度&#xff1a;串口调试助手 blob:https://apps.microsoft.com/df934d29-fd7a-4873-bb6b-a4ab5a7934c9 串口调试助手 Installer.exe 收发的LOG&#xff1a; rootok3588:/# ./uart_test /dev/ttyS0 11520…

C++ bfS

岛屿的最大面积 . - 力扣&#xff08;LeetCode&#xff09; 1.刚开始mn又加了int 2.bfs里符合条件了&#xff0c;不push&#xff0c;&#xff0c;&#xff0c;在写什么几把 class Solution { public:int dx[4] {0, 0, 1, -1};int dy[4] {1, -1, 0, 0};bool vis[50][50];int…

【博士每天一篇文献-算法】Progressive Neural Networks

阅读时间&#xff1a;2023-12-12 1 介绍 年份&#xff1a;2016 作者&#xff1a;Andrei A. Rusu,Neil Rabinowitz,Guillaume Desjardins,DeepMind 研究科学家,也都是EWC(Overcoming catastrophic forgetting in neural networks)算法的共同作者。 期刊&#xff1a; 未录用&am…

调教LLaMA类模型没那么难,LoRA将模型微调缩减到几小时

简介&#xff1a; 调教LLaMA类模型没那么难&#xff0c;LoRA将模型微调缩减到几小时 LoRA 微调方法&#xff0c;随着大模型的出现而走红。 最近几个月&#xff0c;ChatGPT 等一系列大语言模型&#xff08;LLM&#xff09;相继出现&#xff0c;随之而来的是算力紧缺日益严重。虽…

python如何对list求和

如何在Python中对多个list的对应元素求和&#xff0c;前提是每个list的长度一样。比如&#xff1a;a[1&#xff0c;2&#xff0c;3]&#xff0c;b[2&#xff0c;3&#xff0c;4]&#xff0c;c[3&#xff0c;4&#xff0c;5]&#xff0c;对a&#xff0c;b&#xff0c;c的对应元素…

分数计算 初级题目

今天继续更题。今天的题目是《第五单元 分数的加减法》初级题目。 定位&#xff1a;题目较为初级&#xff0c;适合预习 参考答案&#xff1a;CACCADACAABACBBCDBCB

Linux文件系统【真的很详细】

目录 一.认识磁盘 1.1磁盘的物理结构 1.2磁盘的存储结构 1.3磁盘的逻辑存储结构 二.理解文件系统 2.1如何管理磁盘 2.2如何在磁盘中找到文件 2.3关于文件名 哈喽&#xff0c;大家好。今天我们学习文件系统&#xff0c;我们之前在Linux基础IO中研究的是进程和被打开文件…

【DevOps】 什么是容器 - 一种全新的软件部署方式

目录 引言 一、什么是容器 二、容器的工作原理 三、容器的主要特性 四、容器技术带来的变革 五、容器技术的主要应用场景 六、容器技术的主要挑战 七、容器技术的发展趋势 引言 在过去的几十年里,软件行业经历了飞速的发展。从最初的大型机时代,到后来的个人电脑时代,…

【Mongodb-01】Mongodb亿级数据性能测试和压测

mongodb数据性能测试 一&#xff0c;mongodb数据性能测试1&#xff0c;mongodb数据库创建和索引设置2&#xff0c;线程池批量方式插入数据3&#xff0c;一千万数据性能测试4&#xff0c;两千万数据性能测试5&#xff0c;五千万数据性能测试6&#xff0c;一亿条数据性能测试7&am…