【Java 集合】常用的Java集合框架体系详解(134)

news2024/12/23 6:16:36

一、集合的体系

概述:java中存储对象数据的一种容器,集合只能存储引用类型的数据。用泛型来规定需要操作元素的数据类型,可以在编译阶段约束集合只能操作某种数据类型。集合分为两个家族 MAP和Collection

特点:大小不固定(自动扩容,不用定义长度),启动后可以动态变化,类型也可以选择不固定。
集合非常适合做元素的增删操作。 因为数组增删操作比较慢,因此在进行频繁的增删业务的时候就可以选择集合来存储数据。

分类:分为单列集合,双列集合。和数组相比,大小可变更加灵活。

在这里插入图片描述

1. List集合(单列集合)

特点:添加的元素都是有序,可重复,有索引的。

什么是线程不安全
线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据

1.1. ArrayList:
ArrayList是基于动态数组的数据结构;
有索引;
查询效率快:直接通过索引获取元素;
增删效率慢:每改变数组中的任何一个元素,后面元素的索引都要发生变化;

1.2. LinkedList:
LinkedList是基于链表的数据结构;
无索引;
查询效率慢:因为是双向链表结构,需要从头节点开始不断遍历到目标节点,并逐个比对其中的元素;
增删效率快:链表在插入和删除方面很有优势,因为只需要改变相邻节点之间的指针即可;

ArrayList和LinkedList都是线程不安全的:
底层源码没有synchronized 关键字,也就是同步的意思,没有synchronized 就效率高,所有的线程都可以同时访问,不需要排队,只有Vector是线程安全的,底层源码有synchronized 关键字,只能排队访问;

2. Set集合(单列集合)

特点:添加的元素都是无序,不重复(可以去重),无索引的(没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引获取元素)。

  1. 无序性:Set集合中的元素是无序的,不能通过下标或者位置来访问元素。
  2. 元素唯一性:Set集合中的元素是唯一的,不会存在重复的元素。
  3. 可变性:Set集合的元素可以被增加、删除或者修改,因此是可变的。
  4. 哈希表实现:Java中的HashSet是通过哈希表来实现的,因此Set集合的插入、查询和删除操作都具有较快的速度。
  5. 线程不安全:Set集合不是线程安全的,如果需要在多线程环境下使用,需要进行同步处理。
  6. 支持数学中的集合运算:Set集合支持并集、交集、差集等运算,方便我们进行集合的操作。
  7. 不允许重复元素:Set集合中不允许重复元素的存在,当试图添加重复元素时,新元素不会被添加进集合中。
  8. 元素无序性:由于Set集合中元素的存储是无序的,遍历Set集合时获取元素的顺序是不确定的。
  9. 因为Set集合没有索引方法,所以不能用普通的for循环去遍历,也不能通过索引去获取、删除Set集合里面的元素,所以就需要通过迭代器去遍历获取。所有的集合都可以用迭代器去遍历。

2.1. hashSet:
无序、无索引、不重复;

底层:采用哈希表存储数据,哈希表是一种对于增删改查数据性能都比较好的结构;
哈希表的组成:JDK1.8之前:数组+链表;JDK1.8之后:数组+链表+红黑树;

HashSet底层存储数据:通过调用hashCode方法计算对象的哈希值,然后根据哈希值和数组长度计算出对象应存入哈希表的位置,然后该对象再调用equals方法和当前位置的所有对象依次比较,若存在相同属性值对象,则舍弃该对象不存,若不存在属性值相同对象,则将该对象存入当前位置。

注意:一定要重写hashCode和equals方法,这样才能保证实现不重复

哈希值细节
根据hashCode方法算出来的int类型的整数
该方法定义在Object类中,所有对象都可以调用,默认使用地址值进行计算
一般情况下,都会重写hashCode方法,利用对象内部的属性值计算哈希值
如果没有重写hashCode方法,不同对象计算出来的哈希值是不同的
如果重写了hashCode方法,不同对象只有属性值相同,计算出来的哈希值就是一样的
小部分情况下,不同属性值或者不同地址值计算出来的哈希值也有可能一样。(哈希碰撞)

HashSet底层原理
创建一个默认长度16,默认加载因子0.75的数组,数组名table
根据元素的哈希值跟数组的长度计算出应存入的位置
判断当前位置是否为null,如果是null直接存入
如果位置不为null,表示当前位置已经有元素,则调用equals方法比较属性值
一样:表明重复了,不存 ;不一样:存入数组,形成链表(JDK8以前:新元素存入数组,老元素挂在新元素下面;JKD8开始:新元素直接挂在老元素下面)
当元素个数达到16*0.75=12个时,数组会扩容为原来的2倍长度变成32
JDK8以后,当链表长度超过8且数组长度大于等于64时,自动转换为红黑树

如果集合中存储的是自定义对象,必须重写hashCode和equals方法

2.2. treeSet:
不重复、无索引、可排序
可排序:按照元素的默认规则(由小到大)排序
TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都比较好

TreeSet集合默认规则
对于数值类型:Integer,Double,默认是按照从小到大的顺序进行排序
对于字符、字符串类型:按照字符在ASCII码表中的数字升序进行排序

2.3. linkedHashSet:
有序、不重复、无索引
有序指的是存储和取出元素的顺序一致
原理:底层数据结构依然是哈希表,只是每个元素又额外多了一个双链表的机制记录存储的顺序

2.4. SortedSet:
首先是无序不可重复的,但是SortedSet集合中的元素是可排序的。
无序:存进去的顺序和取出的顺序不一定相同。另外Set集合中元素没有下标。
不可重复:存进去1,不能在存储1了。
可排序:可以按照大小顺序排列。

Set集合总结

  1. LinkedHashSet集合的特点和原理是怎样的?
    有序、不重复、无索引
    底层基于哈希表,使用双链表记录添加顺序

  2. 以后如果要数据去重,我们应该使用哪个?
    默认使用HashSet,因为HashSet的效率更高;
    如果要求去重且存取有序,才使用LinkedHashSet;

List,Set集合总结:

  1. 如果想要集合中的元素可重复
    用ArrayList集合,基于数组的。(用的最多)

  2. 如果想要集合中的元素可重复,而且当前的增删操作明显多于查询
    用LinkedList集合,基于链表的

  3. 如果想对集合中的元素去重
    用HashSet集合,基于哈希表的。(用的最多)

  4. 如果想对集合中的元素去重,而且保证存取有序
    用LinkedHashSet集合,基于哈希表和双链表,效率低于HashSet

  5. 如果想对集合中的元素进行排序
    用TreeSet集合,基于红黑树。后续也可以用List集合实现排序

3. Map集合(双列集合)

特点

  1. Map集合是一个双列集合,一个元素包含两个值(一个key,一个value);
  2. Map集合中的元素,key和value的数据类型可以相同,也可以不同;
  3. Map集合中的元素,key是不允许重复的,value是可以重复的;
  4. Map集合中的元素,key和value是一一对应;

3.1. HashMap:
HashMap是Map的实现类;
没有额外需要学习的方法,直接使用Map里面的方法就可以了;
特点都是由键决定的:无序、不重复、无索引;
HashMap跟HashSet地底层原理是一摸一样的,都是哈希表结构;

线程不安全:HashMap是基于哈希表实现的Map,它采用了数组+链表(或红黑树)的数据结构。HashMap中的键值对没有固定的顺序,允许存在一个null键和多个null值。HashMap的性能较好,在大多数场景下都能满足需求。HashMap是非线程安全的,因此在并发场景下需要进行同步处理。

3.2. TreeMap:
TreeMap跟TreeSet底层原理是一样的;
由键决定特性:可排序、不重复、无索引;
可排序:对键进行排序;
注意:默认按照键的从小到大排序,也可以自己规定键的排序规则;

线程不安全:TreeMap是基于红黑树实现的Map,它对键进行排序,因此在遍历时会按照键的自然顺序或者自定义的顺序进行遍历。TreeMap的性能相对较低,适合在键需要排序的场景下使用。

3.3. HashTable:
HashTable,中文意思是哈希表,也叫散列表。HashTable是一种利用哈希函数(Hash Function)进行数据存储的数据结构,通过将键(Key)映射到哈希表中的一个位置来访问记录,以加快查找的速度。一般情况下,哈希表主要包括以下两个部分:哈希函数和哈希表存储数组。哈希函数是将键映射到哈希表中的位置,而哈希表存储数组则用于存储记录。

特点

  1. 快速查找:通过哈希函数可以快速定位到存储的数据位置,因此查找速度快。
  2. 支持高效的插入和删除操作:由于哈希表是通过哈希函数来确定数据存储位置,因此插入和删除数据时只需要计算一次哈希函数即可。所以哈希表的插入和删除操作速度快。
  3. 冲突问题:哈希函数并不是完美的,有时会出现多个键映射到同一个位置的情况,这种情况称为哈希冲突。为了解决哈希冲突问题,哈希表通常采用拉链法或开放寻址法。

缺点

  1. 在多个线程中会发生锁冲突,HashTable是使用一把大锁,锁冲突概率很高
  2. 扩容的速度很慢
  3. size属性同步时也会发生锁冲突,效率变慢

线程安全:hashtable的大部分方法都是由关键字synchronized修饰

3.4. LinkedHashMap:
由键决定:有序、不重复、无索引;
这里的有序指的是保证存储和取出的元素顺序一致;
原理:底层数据结构依然是哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序;

线程不安全:LinkedHashMap是基于哈希表和链表实现的Map,它可以维护键值对的插入顺序,或者按照最近访问的顺序进行遍历。LinkedHashMap是非线程安全的。

3.5. SortedMap:
SortedMap提供有序的Map实现,是对Map集合中键进行总体排序后的映射。

  1. SortedMap接口概述:
    Map的主要实现有HashMap,TreeMap,HashTable,LinkedHashMap。其中的TreeMap实现了SortedMap接口,保证了有序性。默认的排序是根据Key值进行生序排序,也可以重写comparator方法来根据value进行排序。

由于乱序的数据对查找不利,例如无法使用二分法等降低算法的时间复杂度,如果数据在插入时就排好顺序,查找的性能就会提升很多。SortedMap接口就是为这种有序数据服务的,和SortedSet有异曲同工之妙,都是根据键的自然顺序进行排序,或者由通常在排序映射创建时提供的比较器进行排序。这个顺序在遍历排序映射的集合视图(由entrySet、keySet和values方法返回)时可以被体现出来。

  1. SortedMap接口使用原则:
    SortedMap接口需要数据的键(key)需要支持Comparable接口,或者可以被指定的Comparator接受,即SortedMap使用需要遵守如下原则:

插入到排序映射中的所有键都必须实现Comparable接口(或被指定的比较器接受)。
此外,所有这些键必须是相互可比的,即可以执行k1. compareto (k2)或comparator.compare(k1, k2)操作。
不能对排序映射中的任何键k1和k2抛出ClassCastException。尝试违反此限制将导致违规的方法或构造函数调用抛出ClassCastException异常。

3.6. ConcurrentHashMap:
是Java集合框架中的一个并发容器,它是线程安全的哈希表的实现。它被设计为比Hashtable和SynchronizedMap(通过使用同步方法或块来保证线程安全)更高效和可扩展的替代品。
ConcurrentHashMap具有以下特点:

  1. 线程安全:ConcurrentHashMap使用锁分段技术来保证线程安全。它将整个数据结构分成多个段(Segment),每个段都有一个锁来控制对该段的访问。这样,不同的线程可以同时访问不同的段,从而提高并发性能。
  2. 高效性能:ConcurrentHashMap在并发环境下具有良好的性能。它可以支持多个读操作同时进行,而不会阻塞其他线程的写操作。这使得它非常适合于高并发的应用场景。
  3. 可扩展性:ConcurrentHashMap可以根据需要动态地调整其容量大小。当容量达到预设的阈值时,ConcurrentHashMap会自动进行扩容操作,以保证高效的性能。
  4. 可调整的一致性:ConcurrentHashMap提供了不同的一致性级别来满足不同应用场景的需求。它可以使用弱一致性(weak consistency)来提高并发性能,也可以使用强一致性(strong consistency)来保证数据的完整性。

总结:ConcurrentHashMap是Java集合框架中的一个线程安全的哈希表实现,它具有高效性能和可扩展性。通过使用锁分段技术,它可以支持高并发的读写操作,并提供不同的一致性级别来满足不同应用场景的需求。

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

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

相关文章

YOLOv8 YOLOv7 YOLOv5 训练 SCB-Dataset3-U

目录 0 相关资料1 SCB-Dataset3-U 数据2 YOLOv8 训练2.1 YOLOv8 安装2.2 训练的yaml文件2.3 YOLOv8 训练2.3.1 yolov8n 训练2.3.2 yolov8n 验证 0 相关资料 YOLOV8环境安装教程.:https://www.bilibili.com/video/BV1dG4y1c7dH/ YOLOV8保姆级教学视频:https://www.…

实施预测性维护解决方案的挑战及PreMaint的应对方法

前面我们介绍了企业选择预测性维护解决方案的常见问题和PreMaint的策略,本期我们将带来实施过程中可能会遇到的挑战,以及如何通过PreMaint来应对这些挑战,以实现可靠的预测性维护。 随着工业技术的不断进步,预测性维护作为一种先进…

【C语言】结构体内存对齐机制详解

目录 一、前言二、结构体内存对齐规则三、实例解析 一、前言 在讲解结构体内存对齐机制之前,我们先来看1个例子: typedef struct {char sex; // 性别int id; // 学号char name[20]; // 姓名float score; // 成绩char addr[30]; …

中秋特辑——3D动态礼盒贺卡(可监听鼠标移动)

前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 「推荐专栏」: ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄,vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

华纳云:如何搭建Nginx服务器做到负载均衡

要搭建Nginx服务器实现负载均衡,您可以使用Nginx作为反向代理来分发客户端请求到多个后端服务器。以下是一个基本的步骤指南: 前提条件: 您需要一台安装有Nginx的服务器。您需要有多台后端服务器,这些服务器将处理客户端请求。 …

centos7 装机遇到的问题

centos7 U盘启动装机 设置完启动项后重启 在菜单界面选择install centos7 按e编辑启动项,修改成如下 --> 之所以这么改是u盘的LABEL超过长度了只能显示到x8这里,nomodeset 是disable 视频驱动比如gpu 开始安装后如果选择的硬盘没有多余的空间了会提…

TikTok的媒体革命:新闻业如何适应短视频时代?

在数字时代,媒体行业一直在不断演变和创新,以适应观众的变化需求和技术的发展。而在这个进化的过程中,短视频应用TikTok已经崭露头角,成为了一个重要的信息传播平台。 这篇文章将深入探讨TikTok如何引领了媒体的一场革命&#xf…

mininum_snap

位置 速度 加速度 角度 jerk 角速度 驱动力 snap 角加速度 推力的导数 凸优化算法 convex optimization 凸优化(Convex Optimization)是数学和计算机科学领域的一个重要分支,主要研究如何有效地解决凸优化问题。凸优化问题的主要目标是找…

pytest进阶之conftest.py

前言 前面几篇随笔基本上已经了解了pytest 命令使用,收集用例,finxture使用及作用范围,今天简单介绍一下conftest.py文件的作用和实际项目中如是使用此文件! 实例场景 首先们思考这样一个问题:如果我们在编写测试用…

AIMS医院手术麻醉信息系统全套源码,自主版权,开箱即用

手术麻醉临床信息系统有着完善的临床业务功能,能够涵盖整个围术期的工作,能够采集、汇总、存储、处理、展现所有的临床诊疗资料。通过该系统的实施,能够规范麻醉科的工作流程,实现麻醉手术过程的信息数字化,自动生成麻…

如何无损压缩视频?这些技巧你一定用得到

在日常生活中,我们常常会遇到视频文件过大、手机或电脑存储空间不足的情况。这时候,我们就需要将这些视频文件的内存进行压缩,以节省空间。但是,一个一个地压缩视频文件显然是不现实的。那么,如何快速批量压缩视频呢&a…

【马蹄集】—— 数论专题:筛法

数论专题 目录 MT2213 质数率MT2214 元素共鸣MT2215 小码哥的喜欢数MT2216 数的自我MT2217 数字游戏 MT2213 质数率 难度:黄金    时间限制:1秒    占用内存:256M 题目描述 请求出 [ 1 , n ] \left[1,n\right] [1,n] 范围内质数占比率。…

【word技巧】如何限制word页眉,不被他人修改

我们设置了页眉内容之后,不想其他人修改自己的页眉内容,我们可以设置加密的,设置方法如下: 先将页眉设置好,退出页眉设置之后,我们选择布局功能,点击分隔符 – 连续 设置完之后页面分为上下两节…

基于vue3 的 Echarts图表展示(任务一:用柱状图展示消费额最高的省份)(操作全流程)(图文版)

目录 前言: 操作要求: 操作流程: 一.创建vue项目 1.在vscode上创建vue脚手架工程 二.配置运行环境 2.配置axios(用于访问接口) 和引入echarts包 3.引入需要用到的js包 三.开始实践做题(最后附有完整代码) 1.获取接口数据 2.数据处理 …

博格华纳高压发卡式电机解析

博格华纳的高压发卡式电机具有功率强大、坚固耐用和高性能等特点,采用紧凑型设计,优化的导体绕组结构缩短了电机的尺寸,使其便于在更小的空间内进行安装,并提高了常用区间的工作效率。此外,电机在设计上减少了重稀土元…

Spring Cloud Alibaba Nacos 2.2.3 (4) - 本地源码编译 调试

下载nacos nacos在GitHub上有下载地址:https://github.com/alibaba/nacos/releases,可以选择任意版本下载。 我下载的是2.2.3 版本 导入idea mvn 安装包 1,切换到Terminal ,并且使用command prompt模式 2,执行 mvn -Prelease…

Delaunay三角剖分算法

目录 一. 简介1.1 三角剖分1.2 Delaunay三角剖分 二. Delaunay三角剖分的相关理论2.1 Delaunay三角形和(局部)Delaunay边的概念2.2 Delaunay引理2.3 翻转边算法(flip algorithm)2.4 Delaunay三角剖分的最优性质 三. Delaunay三角剖…

缺口的大利润!伦敦银如何使用缺口交易

在伦敦银市场中,我们经常能够看见市场跳空形成缺口,其实,如果利用得当,我们在伦敦银投之中,这些缺口是能够为我们创造盈利机会的,那么下面我们就来讨论一下在伦敦银投之中如何认识这些跳空缺口,…

哪些远程桌面软件适合与团队共享屏幕和文件

远程桌面软件是一种方便团队协作和共享工作的工具。它们能够允许用户通过互联网连接到其他计算机,实现远程访问、共享屏幕和文件、以及协同工作。以下是一些适合与团队共享屏幕和文件的常用远程桌面软件。 1、RayLink RayLink是一款功能强大且易于使用的远程桌面软…

企业微信 API 接口调用教程:图文详解企业微信 API 的使用方法

本文通过 access_token 凭证的方式来讲解怎么调用 企业微信 API,并一步步介绍如何获取企业微信 API 的 corpsecret、corpid、access_token 凭证以及怎么向企业微信的应用发送消息。 企业微信 API 在线地址为:概述 - 企业微信 API ,这个在线地…