Java 常见集合类

集合的整体框架

Java 的集合,也可以叫做容器,根据集合的整体框架可以看出,主要是两大集合接口:第一个是 Collection 接口,主要用来存放单一的元素对象;另一个是 Map 接口,主要用于存储键值对。

Collection 接口有三个子类,List、Set、Queue,下面是抽象类和具体实现类,主要说明具体实现类。常见的有 ArrayList、LinkedList、HsahSet、LinkedHashSet、HsahMap、LinkedHshMap等。

058baa66a2d64680adde65397f1e8ae3.png

集合接口

接口描述
Collection 接口

最基本的集合几口,一个Collection 代表了一组 Object,即 Collection 的元素,Java 提供了继承于它的子接口List、Set、Queue。

存储一组不唯一,无序的对象。

List 接口

特点:有序,不唯一。

使用此接口能精确控制每个元素插入的位置,能够通过索引(类似数组的下标)来访问集合中的元素,同样的,起始于元素索引为 0。

Set 接口

特点:无序,唯一。

Queue 接口队列,按特定的排序规则来确定先后顺序,存放的元素是有序的、可重复的
Map 接口

特点:存放键值对(key-value),key 无序且唯一,value 是无序不唯一的。

算法上常见用来统计数量。

List 和 Set 的区别

特点不同,list 存储的数据有序不唯一,set 存储的数据无序且唯一。

因为索引的存在,list 检索的效率比 set 高,但是 set 的删除和插入的效率高。List 插入元素会改变其他元素的位置。

list 和数组类似,可以动态增长,比如 ArrayList 。

List 接口的实现类

ArrayList

继承并实现了 List 接口,基于动态数组实现,相较于 Array(静态数组) 使用起来更加灵活。

1. ArrayList 动态数组,会根据实际存储的元素动态扩容或缩容,而 Array 被创建之后就不能修改长度,这里涉及到知识点 ArrayList 动态扩容机制。

2. ArrayList 可以使用泛型来确定存储的类型,对于存储的基本数据类型,必须使用对应的包装类(int 的包装类 Integer)来存储。

顺带一提,常见的创建 Arraylist 的方法是

List<Integer> llist = new ArrayList<>();

List 是接口,ArrayList 是具体实现。主要是为了灵活性和可扩展性,这里可以使用List已经定义的方法,不可以使用Arraylist自己的方法,当需要将ArrayList改成其他实现时,只需要将创建集合实例的代码改成想要创建的对象,不用在去修改其他方法代码。

ArrayList 扩容机制

7865c52d3f9845e58c5d6a0cbe7e7cc8.jpg

LinkedList

不同于ArrayList,LinkedList 底层是双向链表。根据链表的特性,每个节点不仅保存了每个元素,还保存了下一个元素的引用。支持随机访问,因为提供了get方法,但是并不高效,假设数据量比较大,需要从首个元素开始遍历,然后查看节点对下一个元素的引用是否为需要的元素,一直循环。

Set 的实现类

对比HashSet、LinkedHashSet、TreeSet。最大的区别就是各自的底层实现不同,分别是哈希表(基于HashMap实现),链表哈希表和红黑树。

Queue

单列队列,遵循队列的先进先出原则,就像排队坐车,先来后到。

Map

HashMap的底层实现

这是一道经典的面试题。在JDK 1.8 以前,HashMap 的底层是数组+链表,通过 哈希函数激素那元素的哈希值,判断元素存储的位置。如果当前位置已经存在了元素,那么就进行判断是否相同,如果不同,就通过拉链法,在数组的后面加上链表来解决哈希冲突。

在JDK1.8之后,底层在数组和链表的基础上,为了解决因为哈希冲突导致链表深度过高的问题,引入了红黑树解决因为深度高导致的查询效率慢。

链表转红黑树:当链表长度大于8时,并且此时数组的容量不小于64时,会把链表转换为红黑树。

红黑树转链表:相反的,因为删除元素导致红黑树的节点不大于6个时,红黑树会重新转换为链表。

为什么选择8作为转换红黑树的阈值。因为根据测算,哈希冲突导致链表长度达到8的概率非常小,几乎到了百万分之一。

为什么选择6作为红黑树转换为链表的阈值。因为如果选取7为阈值,当出现相同元素频繁插入删除,会导致频繁转换,会影响性能。

红黑树的特征

1. 节点颜色:每个节点的都有颜色,红色和黑色。

2. 根节点:根节点总是黑色的

3. 叶子节点:叶子节点都是空节点(NIL 节点)都是黑色。

4. 红色节点限制:不存在连续两个红的节点,红色节点都被黑色节点隔开

5. 路径的和节点:从任一个节点到其后代叶子节点的路径上,包含相同数目的黑色节点。

二叉查找树在一些极端的情况下会出现深度过高,退化成链表的情况,此时查询效率比较低。

之后又出现了自平衡的查找树,比如 AVL,红黑树等。通过定义一些性质,将任意节点的左右子树的高度差控制在规定范围内,达到平衡状态。

不过普通的平衡二叉树可能出现某个路径深度相较其他路径更高,同样会导致效率降低。

红黑树根据后两个而性质,将每个路径的深度差保证在一定范围内。最长的路径不会超过最短路径的两倍。

线程安全的集合

上述的集合都是线程不安全的。线程安全的集合常见的有 ConcurrentHashMap 和 Hashtable。

二者的区别:

首先是底层结构。ConcurrentHashMap 采用的和 HashMap 一样是 数组+链表(红黑树),Hashtable 使用的是 数组+链表 的形式。链表是为了解决哈希冲突存在的。

实现线程安全的方式 

在 JDK1.7的时候,ConcurrentHashMap 对整个桶组进行了分割分段,然后对每段进行加锁,多线程访问不同数据段的数据。

在 JDK 1.8的时候,ConcurrentHashMap 使用 数组和链表红黑树来实现。并发控制使用 synchronized 和 CAS 算法来操作。

Hashtable 使用 synchronized保证线程安全,效率比较低,多个线程访问同一个方法是可能会出现阻塞。

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

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

相关文章

Linux·基本指令

从本节开始将新开一个关于Linux操作系统的板块&#xff0c;其实Linux也没什么太神秘的&#xff0c;就是一个操作系统(OS)嘛&#xff0c;跟Windows操作系统是一个概念&#xff0c;只不过Windows中的大部分操作都是用光标点击来进行人机交互&#xff0c;但是Linux是通过输入命令行…

SQLite性能测试(插入)

最近一直在思考一个问题&#xff0c;SQLite 做到这么轻量级&#xff0c;那它注定不会像 MySql 一样强性能&#xff0c;那么它的性能怎么样呢&#xff1f;并发量多高呢&#xff1f; 官方解释&#xff1a; About SQLite 最大数据库大小&#xff1a;281TB 最大行大小&#xff1…

俄罗斯方块的代码实现

文章目录 首先是头文件的引入部分接下来是一些预处理指令接下来定义了两个结构体&#xff1a;接下来是全局变量g_hConsoleOutput&#xff0c;用于存储控制台输出句柄。之后是一系列函数的声明最后是main函数源码 首先是头文件的引入部分 包括stdio.h、string.h、stdlib.h、tim…

Neo4j 之安装和 CQL 基本命令学习

正常使用结构化的查询语言 SQL&#xff08;Structured Query Language&#xff09;较多一些&#xff0c;但是像 Neo4j 这种非结构化的图形数据库来说&#xff0c;就不得不学习下 CQL&#xff08;Cypher Query Language&#xff09;语言了。如果你之前学过 《离散数学》或《图论…

【北京迅为】《iTOP-3588从零搭建ubuntu环境手册》-第6章 安装Samba

RK3588是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…

Debian安装Redis、RabbitMQ、Nacos

安装Redis&#xff1a; 启动Redis、开机自启动 sudo systemctl start redis-server #启动sudo systemctl enable redis-server #开机自启 Redis状态(是否在运行) sudo systemctl status redis-server #查看运行状态 redis-cli ping # 客户端尝试连接 安装RabbitMQ&#xff0c;…

Rust学习笔记(中)

前言 笔记的内容主要参考与《Rust 程序设计语言》&#xff0c;一些也参考了《通过例子学 Rust》和《Rust语言圣经》。 Rust学习笔记分为上中下&#xff0c;其它两个地址在Rust学习笔记&#xff08;上&#xff09;和Rust学习笔记&#xff08;下&#xff09;。 错误处理 pani…

百问C语言第1问——彻底弄懂define用法

系列文章目录 玩转指针专栏 趣味c程序专栏 一.c语言关系操作符练习题(新手必会) 一.c语言常见概念(超全) 一.趣味c程序—关机程序&#xff08;整蛊同学版) 二.趣味c程序—猜数字游戏&#xff08;含干货知识点 三.趣味c程序—打印图形&#xff08;1&#xff09;&#xff08;含干…

前端笔记-day05

文章目录 01-结构伪类选择器02-结构伪类选择器-公式用法03-伪元素选择器04-盒子模型-组成05-盒子模型-边框线06-盒子模型-单方向边框线07-盒子模型-内边距08-盒子模型-padding多值写法09-盒子模型-尺寸计算10-盒子模型-版心居中11-清除默认样式12-元素溢出overflow13-外边距合并…

Java | Leetcode Java题解之第83题删除排序链表中的重复元素

题目&#xff1a; 题解&#xff1a; class Solution {public ListNode deleteDuplicates(ListNode head) {if (head null) {return head;}ListNode cur head;while (cur.next ! null) {if (cur.val cur.next.val) {cur.next cur.next.next;} else {cur cur.next;}}return…

E - Yet Another Sigma Problem(ABC字典树)

思路&#xff1a;我们可以发现两个字符串的最长公共前缀就是字典树中的最近公共祖先。然而这道题&#xff0c;比如说某个结点是x个字符串的前缀&#xff0c;那么当前结点对答案的贡献为x * (x - 1) / 2&#xff0c;就是x中任选两个字符串组合&#xff0c;因为在这之前&#xff…

Linux提权--本地环境变量文件配合 SUID

免责声明:本文仅做技术交流与学习... 目录 背景: 前提条件: 演示: 实战中如何操作? 探针发现: 背景: 环境变量提权--------> 背景&#xff1a; 管理员编译了程序&#xff0c;给予了程序管理员运行的方案, 攻击通过对程序的运行调试反编译等得到了程序的运行大概逻辑, …

软考-软件工程

软件工程概述 软件工程指的是应用计算机科学、数学及管理科学等原理&#xff0c;以工程化的原则和方法来解决软件 问题的工程&#xff0c;目的是提高软件生产率、提高软件质量、降低软件成本。 概述&#xff1a; 软件开发模型&#xff1a;指导软件开发的体系 需求分析确定软件…

使用Remix部署智能合约到币安链(Remix的操作介绍 币安链合约的部署) 点赞收藏哦

大家好&#xff0c;我是程序员大猩猩呀。 据我所知&#xff0c;很多人进入币圈之后&#xff0c;想要通过炒币一夜暴富&#xff01;另一部分人呢他们希望自己能创建一个项目&#xff0c;然后发行自己的数字货币然后暴富。 不管是什么方式吧&#xff0c;只要不违法&#xff0c;…

原创未发表!24年新算法SBOA优化TVFEMD实现分解+四种熵值+频谱图+参数变化图+相关系数图!

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 数据介绍 优化流程 创新点 使用TVFEMD的创…

【详细介绍下Visual Studio】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

树莓派、ubuntu低版本python3安装库

如果遇到树莓派中自带低版本python3&#xff0c;又不想额外去安装python3时&#xff0c;可能会遇到版本过低&#xff0c;无法安装库的情况&#xff0c;以下用我实际情况举例解决方案。 本次遇到的问题是树莓派低版本中&#xff0c;python3为3.7.3&#xff0c;需要安装numpy&am…

数据结构与算法学习笔记三---循环队列的表示和实现(C语言)

目录 前言 1.为啥要使用循环队列 2.队列的顺序表示和实现 1.定义 2.初始化 3.销毁 4.清空 5.空队列 6.队列长度 7.获取队头 8.入队 9.出队 10.遍历队列 11.完整代码 前言 本篇博客介绍栈和队列的表示和实现。 1.为啥要使用循环队列 上篇文章中我们知道了顺序队列…

【数据结构】静态链表

静态链表 1.静态链表的结构设计&#xff1a; typedef struct SNode {int data; // 数据int next; //后继指针&#xff08;下标&#xff09; }SNode, SLinkList[MAXSIZE];2.静态链表的结构示意图 0&#xff1a;有效数据链的头结点 1&#xff1a;空闲数据链的头结点 3.静态链表…

重生奇迹mu再生宝石怎么用有什么用

重生奇迹mu再生宝石有2个用处&#xff1a; 1、在玛雅哥布林处给380装备加PVP属性4追4以上的380级装备,守护宝石一颗,再生宝石一颗,成功得到PVP装备,失败宝石消失,装备无变化&#xff1b; 2、给非套装点强化属性用法跟祝福,灵魂,生命一样直接往装备上敲,成功得到随机强化属性一…