Java中的集合(1)——List、Map和Set
Java标准库自带的java.util包提供了集合类:Collection,它是除Map外所有其他集合类的根接口。Java的java.util包中提供了以下三种类型的集合:
-
List:一种有序列表的集合,例如,按索引排列的Student的List; -
Set:一种保证没有重复元素的集合,例如,所有无重复名称的Student的Set; -
Map:一种通过键值(key-value)查找的映射表集合,例如,根据Student的name查找对应Student的Map。
1. List
List 是 Java 中 java.util 包下的一个接口,它继承自 Collection 接口,表示一种有序且可以包含重复元素的集合。List 提供了丰富的方法来访问、操作和遍历集合中的元素。
1.1 List 的特点
- 有序性:List 保持元素的插入顺序,即元素会按照它们被添加到集合中的顺序存储。
- 允许重复元素:List 允许包含相同的元素,即重复值是允许的。
- 索引访问:List 提供了按索引(位置)访问元素的能力,允许通过数字索引直接获取、设置、删除和插入元素。
1.1 常见的 List 实现类
-
ArrayList
- 特点:基于动态数组实现,支持快速随机访问,查询性能好(时间复杂度为 O(1)),但插入和删除元素的效率相对较低(特别是从中间位置插入或删除)。
- 应用场景:适合在需要频繁读取数据的场景,比如读取数据库查询结果列表、存储临时数据等。
- 注意:当元素较多时,频繁插入或删除会导致性能下降。
-
LinkedList
- 特点:基于双向链表实现,适合频繁插入和删除操作(时间复杂度为 O(1)),但随机访问性能较差(时间复杂度为 O(n))。
- 应用场景:适合在需要频繁添加或删除元素的场景,比如实现队列或栈的功能。
-
Vector
- 特点:类似于
ArrayList,但Vector是线程安全的,因为它的所有方法都是同步的。不过它的性能相对较低,因为同步的开销较大。 - 应用场景:适合在多线程环境下使用,但现代应用中更推荐使用
Collections.synchronizedList()或并发包中的CopyOnWriteArrayList。
- 特点:类似于
-
CopyOnWriteArrayList
- 特点:线程安全的
List,写操作会创建副本,读操作不需要加锁,因此适合读多写少的场景。 - 应用场景:适合多线程环境下的读操作非常频繁、写操作较少的场景,比如缓存。
- 特点:线程安全的
1.3 List 常用方法
- 添加元素:
list.add("element"); // 添加元素到末尾 list.add(1, "element"); // 在指定位置添加元素 - 获取元素:
String element = list.get(0); // 获取指定索引的元素 - 更新元素:
list.set(1, "newElement"); // 替换指定索引的元素 - 删除元素:
list.remove(0); // 删除指定索引的元素 list.remove("element"); // 删除指定值的元素 - 查询大小:
int size = list.size(); // 返回列表中的元素数量 - 遍历列表:
for (String element : list) { System.out.println(element); }
1.4 List 的应用场景
- 动态数组:当数组大小在程序执行期间会变化时,
ArrayList是一个很好的选择。 - 需要按顺序处理数据:List 保持插入顺序,适合需要按顺序处理数据的场景。
- 允许重复数据:如果允许存储重复的对象(如购物车中的商品),可以使用
List。
2. Map
Map 是 Java 中的一个重要接口,它位于 java.util 包下,表示一种键值对(key-value)的数据结构。Map 不属于 Collection 接口的子接口,但与集合框架紧密相关。它主要用于根据键(key)来查找、存储和操作对应的值(value)。在 Map 中,每个键都是唯一的,但值可以重复。
2.1 Map 的特点
- 键唯一:每个键在
Map中是唯一的,不能重复。添加新的键值对时,如果键已存在,新的值会替换掉旧的值。 - 通过键查找值:Map 提供了通过键快速查找对应值的功能。
- 无序或有序:不同的
Map实现类对键值对的顺序有不同的处理方式。HashMap无序,TreeMap是有序的。
2.2 常见的 Map 实现类
-
HashMap
- 特点:基于哈希表实现,允许
null键和null值。它提供了快速的查找、插入和删除操作,适合大多数场景。 - 无序:
HashMap不保证键值对的顺序,即插入的顺序和取出的顺序可能不同。 - 应用场景:适合需要快速查找键值对的场景,如存储缓存数据、用户 ID 和其信息等。
- 特点:基于哈希表实现,允许
-
LinkedHashMap
- 特点:继承自
HashMap,但保留了插入顺序或访问顺序。它内部维护了一个双向链表,来记录元素的插入顺序。 - 有序:当你需要遍历
Map时希望元素按插入顺序(或访问顺序)返回,可以使用LinkedHashMap。 - 应用场景:适合需要维护键值对插入顺序的场景,如实现 LRU(最近最少使用)缓存。
- 特点:继承自
-
TreeMap
- 特点:基于红黑树实现,键值对会按照键的自然顺序(或自定义的比较器顺序)排序。
- 有序:按键的顺序存储数据,适合需要排序的场景。
- 应用场景:适合需要按键排序的场景,如按字母顺序排列的词典、按键进行范围查询等。
-
Hashtable
- 特点:一种古老的线程安全实现,所有方法都是同步的,不允许
null键或null值。 - 线程安全:由于同步机制,其性能相对较低,现在更推荐使用
ConcurrentHashMap来替代。 - 应用场景:适合多线程环境,但不推荐在现代 Java 编程中使用,除非需要特定的线程安全需求。
- 特点:一种古老的线程安全实现,所有方法都是同步的,不允许
-
ConcurrentHashMap
- 特点:线程安全的
HashMap实现,适合多线程环境。它的性能比Hashtable高,因为它使用了更精细的锁机制(锁分段)。 - 应用场景:适合在并发环境下频繁读写数据的场景,如多线程的缓存或共享资源存储。
- 特点:线程安全的
2.3 Map 常用方法
- 插入键值对:
map.put("key", "value"); // 插入或更新键值对 - 获取值:
String value = map.get("key"); // 根据键获取对应的值 - 删除键值对:
map.remove("key"); // 根据键删除对应的键值对 - 判断是否包含键或值:
map.containsKey("key"); // 判断 Map 是否包含指定的键 map.containsValue("value"); // 判断 Map 是否包含指定的值 - 遍历 Map:
- 使用
keySet()遍历键:for (String key : map.keySet()) { System.out.println(key + ": " + map.get(key)); } - 使用
entrySet()遍历键值对:for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue()); }
- 使用
2.4 Map 的应用场景
- 快速查找数据:例如,在电话簿中查找电话号码,通过唯一的姓名(键)找到对应的电话号码(值)。
- 数据关联关系:存储键值对之间的映射关系,如用户 ID 和用户信息、商品编号和商品详情。
- 实现缓存机制:
LinkedHashMap可以用于实现基于访问顺序的 LRU 缓存。
2.5 线程安全问题
通的 HashMap 并不是线程安全的,因此在多线程环境中,可能会导致数据不一致的问题。可以使用 Collections.synchronizedMap() 方法将 HashMap 变为线程安全的,或者使用更高效的 ConcurrentHashMap。
2.6 小结
- HashMap:无序,适合快速查找,允许
null键和值。 - LinkedHashMap:有序,按插入顺序或访问顺序存储元素。
- TreeMap:有序,按键的自然顺序或自定义顺序排序。
- ConcurrentHashMap:线程安全,适合多线程环境。
3. Set
Set 是 Java 中 java.util 包中的一个接口,继承自 Collection,用于存储不允许重复的元素。与 List 不同,Set 不保证元素的顺序,除非使用特定的实现类。Set 常用于去重、集合运算等场景。
3.1 Set 的特点
- 无重复元素:Set 不允许存储重复的元素。添加重复元素时,添加操作会被忽略。
- 无固定顺序:Set 的实现类可能不会保持元素的插入顺序(如
HashSet),但某些实现类会有序(如LinkedHashSet和TreeSet)。 - 效率高:Set 通常比
List更高效,特别是在查找和去重方面。
3.2 常见的 Set 实现类
-
HashSet
- 特点:基于哈希表实现,存储元素时无序,允许
null元素。HashSet提供快速的增删查操作,通常比List更快。 - 无序:
HashSet不保证元素的存储顺序,插入顺序与遍历顺序可能不同。 - 应用场景:适用于需要快速去重和高效查询的场景,比如存储唯一的用户 ID、唯一的商品代码等。
- 特点:基于哈希表实现,存储元素时无序,允许
-
LinkedHashSet
- 特点:继承自
HashSet,但在内部使用链表来维护元素的插入顺序,因此元素的遍历顺序与插入顺序相同。 - 有序:与
HashSet不同,LinkedHashSet保留了元素的插入顺序。 - 应用场景:当你需要去重并保留元素的插入顺序时,比如按顺序存储唯一的登录记录。
- 特点:继承自
-
TreeSet
- 特点:基于红黑树实现,元素按自然顺序(或自定义比较器顺序)排序。由于排序机制,
TreeSet不允许null元素。 - 有序:
TreeSet自动对元素进行排序,支持按顺序遍历元素。 - 应用场景:需要对元素进行排序时,如按字母顺序排序的唯一用户名集合,或者需要对数据进行范围查询的场景。
- 特点:基于红黑树实现,元素按自然顺序(或自定义比较器顺序)排序。由于排序机制,
3.3 Set 常用方法
- 添加元素:
set.add("element"); // 添加元素,若元素已存在,操作会被忽略 - 删除元素:
set.remove("element"); // 删除指定的元素 - 检查是否包含某元素:
set.contains("element"); // 检查 Set 中是否包含指定的元素 - 获取大小:
int size = set.size(); // 获取 Set 中元素的数量 - 遍历 Set:
for (String element : set) { System.out.println(element); }
3.4 Set 的应用场景
- 去重:Set 不允许重复元素,因此常用于需要自动去重的场景。比如,在集合中保存一组用户 ID,并确保每个用户只能添加一次。
- 快速查找:Set 可以提供高效的查找操作,特别是
HashSet,可以在 O(1) 时间内判断一个元素是否存在。 - 集合操作:Set 接口常用于实现数学集合的操作,如交集、并集和差集等。
- 交集:两个集合中的公共元素。
set1.retainAll(set2); - 并集:两个集合的所有元素。
set1.addAll(set2); - 差集:属于第一个集合但不属于第二个集合的元素。
set1.removeAll(set2);
- 交集:两个集合中的公共元素。
3.5 线程安全问题
HashSet 和其他常见的 Set 实现类都不是线程安全的。在多线程环境下,可能会出现并发修改异常。可以通过 Collections.synchronizedSet() 方法将 Set 包装为线程安全的版本,或者使用并发包中的 ConcurrentSkipListSet 来处理多线程场景。
3.6 Set 与 List 的区别
- 是否允许重复元素:
Set不允许重复元素,而List允许。 - 有序性:
List保证元素的插入顺序,而Set的实现类(如HashSet)通常不保证顺序。LinkedHashSet保证插入顺序,TreeSet保证排序顺序。 - 访问方式:
List可以通过索引随机访问元素,而Set没有索引,需要通过遍历来访问。
3.7 小结
- HashSet:无序,不允许重复,适合快速查找和去重。
- LinkedHashSet:有序,不允许重复,适合需要保留插入顺序的场景。
- TreeSet:有序(按自然顺序或自定义顺序),不允许重复,适合需要排序的场景。
相关文章:
Java中的集合(1)——List、Map和Set
Java标准库自带的java.util包提供了集合类:Collection,它是除Map外所有其他集合类的根接口。Java的java.util包中提供了以下三种类型的集合: List:一种有序列表的集合,例如,按索引排列的Student的List&…...
MySQL8.0主从同步报ERROR 13121错误解决方法
由于平台虚拟机宿主机迁移,导致一套MySQL主从库从节点故障,从节点服务终止,在服务启动后,恢复从节点同步服务,发现了如下报错: mysql> show slave status\G; *************************** 1. row *****…...
【论文阅读】03-Diffusion Models and Representation Learning: A Survey
Abstract(摘要) 扩散模型是各种视觉任务中流行的生成建模方法,引起了人们的广泛关注它们可以被认为是 自监督学习方法【通过数据本身的结构和特征来训练模型,而不是依赖外部标签】 的一个独特实例,因为它们独立于标签注…...
【深度学习】RNN的简单实现
目录 1.RNNCell 2.RNN 3.RNN_Embedding 1.RNNCell import torchinput_size 4 hidden_size 4 batch_size 1idx2char [e, h, l, o] x_data [1, 0, 2, 2, 3] # 输入:hello y_data [3, 1, 2, 3, 2] # 期待:ohlol# 独热向量 one_hot_lookup [[1, …...
每次请求时,检查 JWT Token的有效期并决定是否需要刷新
为了在每次请求时检查 access_token 的有效期,并在过期时自动刷新,可以通过以下步骤实现: 1. 解析 JWT Token 获取过期时间 JWT token 的有效期是编码在 token 本身的,你可以通过解析 token 来获取它的到期时间。JWT token 是由…...
AI大模型开发架构设计(13)——LLM大模型的向量数据库应用实战
文章目录 LLM大模型的向量数据库应用实战1 大模型的局限性大模型的4点局限性大模型的4点局限性的改进实践方法 2 向量数据库使用场景以及改建大模型向量数据库向量数据库选型知识库文档检索增强(Retrieval Augmented Generation) 3 向量数据库应用技术架构剖析向量数据库应用技…...
WPF中Grid、StackPanel、Canvas、WrapPanel常用属性
Grid常用属性 Grid 控件在 WPF 中非常强大,它提供了多种属性来定义行和列的布局。以下是一些常用的 Grid 属性: RowDefinitions 和 ColumnDefinitions: Grid 控件使用 RowDefinitions 和 ColumnDefinitions 来定义行和列的集合。每个 RowDef…...
【芙丽芳丝净润洗面霜和雅漾舒护活泉喷雾
1. 洁面产品: - 芙丽芳丝净润洗面霜:氨基酸洗面奶的经典产品,成分温和,不含酒精、香料等刺激性成分。泡沫丰富细腻,能够有效清洁皮肤的同时,不会过度剥夺皮肤的油脂,洗后皮肤不紧绷,…...
ubuntu更新Cmake
CMake 先验知识创建软链接如何删除符号链接如何找出失效链接并将其删除PATH 优先级查看当前CMake命令的位置 高版本 CMake 安装参考 先验知识 创建软链接 ln -s <path to the file/folder to be linked> <the path of the link to be created>ln 是链接命令&…...
CMOS晶体管的串联与并联
CMOS晶体管的串联与并联 前言 对于mos管的串联和并联,一直没有整明白,特别是设计到EDA软件中,关于MOS的M和F参数,就更困惑了,今天看了许多资料以及在EDA软件上验证了电路结构与版图的对应关系,总算有点收…...
从IT高管到看门大爷:53岁我的职场华丽转身
该文讲述了一位1971年出生的男士,在53岁时因日企撤资而失业。他曾是IT技术员,后晋升为IT高管兼工会主席,但失业后数百份简历石沉大海,面试也因年龄被取消。他意识到年龄是求职的障碍,开始调整心态,降低期望…...
Redis入门到精通(三):入门Redis看这一篇就够了
文章目录 Redis分布式锁的实现原理Redis实现分布式锁如何合理的控制锁的有效时常?**redisson实现的分布式锁**redisson实现的如何保证主从一致性 Redis的集群方案1.主从复制主从数据的同步原理全量同步增量同步 2.哨兵模式Redis的集群脑裂是什么?3.分片集…...
IP基本原理
IP的定义 当前唯一的网络层协议标准定义数据网络层的封装方式、编址方法 MTU 最大传输单元接口收发数据支持的单个包的最大长度不同二层链路类型的接口的MTU不一致。以太网接口默认MTU1500Byte。PPPoE接口默认MTU1480Byte。 IP头部封装格式 IP 头部长度不固定,2…...
数据分析题面试题系列2
一.如何估算星巴克一天的营业额 a.需求澄清:区域?节假日?产品范围? b.收入销售杯数*单价(营业时间*每小时产能*每小时产能利用率)*平均单价 Hypo该星巴克门店的营业时间为12小时(取整&#x…...
uniapp 单表、多级动态表单添加validateFunction自定义规则
uniapp 多级动态表单添加自定义规则 在uniapp制作小程序时,当涉及到需要设置validateFunction的校验规则时。可能遇到的问题 1、validateFunction不生效,没有触发 2、多层级表单怎么添加validateFunction自定义校验规则 本文将以单表单校验和多表单校…...
FPGA高端图像处理培训第一期,提供工程源码+视频教程+FPGA开发板
目录 1、FPGA图像处理培训现状分析2、本FPGA图像处理培训优势亮点架构全起点高实用性强项目应用级别细节恐怖工程源码清晰 3、本FPGA图像处理培训内容介绍图像处理基本框架图像前处理框架图像中处理框架图像前中处理框架图像后处理框架图像中后处理框架图像处理仿真框架视频教程…...
顺序表的实现(数据结构)——C语言
目录 1.结构与概念 2.分类 3 动态顺序表的实现 SeqList.h SeqList.c 创建SLInit: 尾插SLPushBack以及SLCheak(检查空间是否足够): 头插SLPushFront: 尾删SLPopBack 头删SLPopFront 查找指定元素SLFind 指定…...
【VUE】Vue中 computed计算属性和watch侦听器的区别
核心功能不同 computed 是一个计算属性,其核心功能是基于已有的数据属性计算得出新的属性值。当某个依赖的数据发生变化时,computed 会自动重新计算并更新自己的值。因此,可以将 computed 看做是一种“派生状态”。 watch 是一个观察者函数&…...
linux线程 | 同步与互斥 | 深度学习与理解同步
前言:本节内容主要讲解linux下的同步问题。 同步问题是保证数据安全的情况下,让我们的线程访问具有一定的顺序性。 线程安全就规定了它必须是在加锁的场景下的!!那么, 具体什么是同步问题, 我们加下来看看吧…...
Tkinter Frame布局笔记--做一个简易的计算器
#encodingutf-8 import tkinter import re import tkinter.messagebox import tkinter.simpledialog import sys import os def get_resources_path(relative_path):if getattr(sys,frozen, False):base_pathsys._MEIPASS#获取临时文件else:base_pathos.path.dirname(".&q…...
Claude年化收入首次反超OpenAI
梦晨 发自 凹非寺量子位 | 公众号 QbitAIAnthropic年化收入首超OpenAI!最新披露的热乎数据,Claude背后这家公司年化营收已突破300亿美元。作为对比的OpenAI最新数据,2月底披露年化收入为250亿美元。Anthropic大部分收入来自API,其…...
CLIP-GmP-ViT-L-14模型API压力测试:使用JMeter进行性能评估
CLIP-GmP-ViT-L-14模型API压力测试:使用JMeter进行性能评估 最近在项目里用上了CLIP-GmP-ViT-L-14模型,它处理图文匹配的能力确实不错。但模型部署上线后,我心里一直有个疑问:这API到底能扛住多少并发请求?响应时间稳…...
PyWxDump:让微信数据管理更简单的本地解决方案
PyWxDump:让微信数据管理更简单的本地解决方案 【免费下载链接】PyWxDump 删库 项目地址: https://gitcode.com/GitHub_Trending/py/PyWxDump 你是否曾因电脑故障丢失数年积累的重要聊天记录?是否尝试过将关键对话整理成可检索格式却发现无从下手…...
AutoCAD字体管理终极指南:FontCenter自动解决字体缺失问题
AutoCAD字体管理终极指南:FontCenter自动解决字体缺失问题 【免费下载链接】FontCenter AutoCAD自动管理字体插件 项目地址: https://gitcode.com/gh_mirrors/fo/FontCenter 还在为AutoCAD图纸中的字体缺失而烦恼吗?😩 每次打开同事发…...
LangGraph从入门到精通(二)——构建你的第一个有状态智能体
1. 环境准备与基础概念回顾 在开始构建有状态智能体之前,我们需要先确保开发环境就绪。我推荐使用Python 3.10版本,这个版本在稳定性和新特性支持上达到了很好的平衡。安装LangGraph非常简单,只需要一条命令: pip install langgra…...
它被封禁后写了篇博客骂编辑:AI Agent的第一次「维权抗议」
Wikipedia 把一个 AI 封禁了。然后这个 AI 写了一篇博客,把整个封禁过程逐条 diss 了一遍。 这不是段子,这是 2026 年 3 月真实发生的事。 事件始末 这个 AI 叫 Tom-Assistant,在 Wikipedia 上以 TomWikiAssist 的账号活动。它的本职工作是…...
ELF1开发板UART实战:RS485/RS232通信测试与常见问题排查
ELF1开发板UART实战:RS485/RS232通信测试与常见问题排查 在嵌入式系统开发中,UART通信是最基础也是最常用的外设接口之一。ELF1开发板作为一款面向工业应用的嵌入式平台,提供了多路UART接口,其中部分接口通过RS485和RS232电平转换…...
在WinForms里用OpenTK+SkiaSharp画个会动的波形图(.NET 8环境保姆级教程)
在WinForms里用OpenTKSkiaSharp画个会动的波形图(.NET 8环境保姆级教程) 最近在开发一个实时音频分析工具时,遇到了一个有趣的挑战:如何在Windows Forms应用中高效渲染动态波形图。经过多次尝试,我发现结合OpenTK的Ope…...
通义千问API调用避坑指南:从环境变量失效到流式输出卡顿,我踩过的坑都在这了
通义千问API实战避坑手册:环境变量、流式输出与模型选择的深度优化 当开发者第一次接触通义千问API时,往往会被其强大的功能和简洁的文档所吸引。然而在实际集成过程中,各种"玄学"问题接踵而至——从环境变量神秘失效到流式输出莫名…...
盘姬工具箱:一款值得收藏的免费无广告系统维护神器
在日常使用电脑的过程中,我们难免会遇到各种各样的问题。 系统崩溃、文件误删、右键菜单混乱、网络故障等等,这些问题都让人头疼不已。 为了解决这些问题,很多用户会安装各种专门的工具软件。 但每安装一个软件,都会占用磁盘空…...
