当前位置: 首页 > news >正文

理解Java集合的基本用法—Collection:List、Set 和 Queue,Map

本博文部分参考 博客 ,强烈推荐这篇博客,写得超级全面!!!


图片来源

Java 集合框架

主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合(单列集合);另一种是 Map ,存储键/值对映射。
Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类。

  • Collection:所有单列集合的根接口。

    • List:有序、允许重复元素的集合。

    • Set:无序、不允许重复元素的集合。

    • Queue:用于存储按特定顺序处理的元素(如先进先出 FIFO)。

  • Map:映射接口(双列接口),用于存储键值对(Key-Value),提供对键值的快速查找。

在这里插入图片描述
图片来源

由于Java的集合设计非常久远,中间经历过大规模改进,我们要注意到有一小部分集合类是遗留类,不应该继续使用:

  • Hashtable:一种线程安全的Map实现;
  • Vector:一种线程安全的List实现;
  • Stack:基于Vector实现的LIFO的栈。

还有一小部分接口是遗留接口,也不应该继续使用:

  • Enumeration:已被Iterator取代。

List(有序集合,允许重复元素)

List 是一个有序的集合,元素按插入顺序排列,允许重复元素。
实现类:

  • ArrayList 基于动态数组实现,支持随机访问和快速查找,但插入和删除操作的性能较差,尤其是在中间位置操作时。
  • LinkedList 基于双向链表实现,插入和删除操作效率较高,适合频繁的插入和删除,但随机访问的性能差。
  • Vector(ArrayList是非线程安全的,效率高;Vector是基于线程安全的 List 实现,效率低 ,遗留类,通常不推荐使用) 。

ArrayList 是最常用的 List 实现类。

List<String> list = new ArrayList<>();

常用方法:

  • boolean add(E element):在末尾添加一个元素。
  • boolean add(int index, E element):在指定索引添加一个元素。
  • E get(int index):获取指定索引的元素。
  • E set(int index, E element):设置指定位置的元素,返回先前在 index 处出现的元素。
  • boolean remove(Object o):删除指定元素。
  • E remove(int index):删除指定索引的元素。
  • int size():获取集合大小。
  • boolean contains(Object o):判断是否包含某元素。
  • int indexOf(Object o):可以返回某个元素的索引,如果元素不存在,就返回-1。

我们来比较一下 ArrayListLinkedList

ArrayListLinkedList
获取指定元素速度很快需要从头开始查找元素
添加元素到末尾速度很快速度很快
在指定位置添加/删除需要移动元素不需要移动元素
内存占用较大

通常情况下,我们总是优先使用 ArrayList

另外,我们要始终坚持使用迭代器 Iterator 来访问 List ,因为总是具有最高的访问效率。

public class Main {public static void main(String[] args) {List<String> list = List.of("apple", "pear", "banana");for (Iterator<String> it = list.iterator(); it.hasNext(); ) {String s = it.next();System.out.println(s);}}
}

Java 的 for each 循环本身可以帮我们使用 Iterator 遍历。可以把上面的代码改写成:

ublic class Main {public static void main(String[] args) {List<String> list = List.of("apple", "pear", "banana");for (String s : list) {System.out.println(s);}}
}

List 可以和 Array 相互转换:

把 List 变为 Array 有三种方法

  1. 调用toArray()方法直接返回一个Object[]数组,这种方法会丢失类型信息,所以实际应用很少。
List<String> list = List.of("apple", "pear", "banana"); // 如果我们调用List.of(),它返回的是一个只读List
Object[] array = list.toArray();
  1. 给 toArray(T[]) 传入一个类型相同的 Array,List 内部自动把元素复制到传入的 Array 中。
List<Integer> list = List.of(12, 34, 56); //如果我们调用List.of(),它返回的是一个只读List
Integer[] array = list.toArray(new Integer[list.size()]);
  1. 通过List接口定义的T[] toArray(IntFunction<T[]> generator)方法。
Integer[] array = list.toArray(Integer[]::new);

把 Array 变为 List,通过 List.of(T…) 方法最简单

Integer[] array = { 1, 2, 3 };
List<Integer> list = List.of(array);

总结

  • List 是按索引顺序访问的长度可变的有序表,优先使用 ArrayList 而不是 LinkedList;

  • 可以直接使用 for each 遍历 List;

  • List 可以和 Array 相互转换。


Set(无序集合,不允许重复元素)

Set 是一个不允许重复元素的集合,它不保证元素的顺序。Set 实际上相当于只存储 key、不存储 value 的 Map。我们经常用 Set 用于去除重复元素。

Set 接口并不保证有序,而 SortedSet 接口则保证元素是有序的。PS:注意输出的顺序既不是添加的顺序,也不是 String 或 Integer 排序的顺序,在不同版本的JDK中,这个顺序也可能是不同的。
实现类:

  • HashSet 基于哈希表实现,元素无序,性能较好,适合用于查找。它实现了Set接口,并没有实现SortedSet接口;
  • LinkedHashSet 基于哈希表和链表实现,元素有序(按插入顺序)。
  • TreeSet 基于红黑树实现,元素按自然顺序(或提供的 Comparator)排序。它实现了SortedSet接口。

HashSet 是 Set 接口最常用的实现

Set<String> set = new HashSet<>();

常用方法:

  • boolean add(E e):添加元素。
  • boolean remove(Object o):删除指定元素。
  • boolean contains(Object o):判断是否包含某元素。
  • int size():获取集合大小。
  • clear():清空集合。

Queue / Deque

Queue 是一个先进先出(FIFO:First In First Out)的集合,只能一头进,另一头出。

实现类:

  • PriorityQueue:基于优先级堆实现,支持优先级排序的队列。PriorityQueue 并不是一个比较标准的队列实现,PriorityQueue 保存队列元素的顺序并不是按照加入队列的顺序,而是按照队列元素的大小进行重新排序。

  • Deque:Queue 是队列,只能一头进,另一头出。双端队列 Deque(Double Ended Queue)允许两头都进,两头都出。

    • ArrayDeque:基于数组实现,作为栈或队列使用,效率较高。

    • LinkedList:实现了 Queue 接口,适合用于队列操作。

Queue<String> queue = new LinkedList<>();

Queue

常用方法

  • boolean add(E) / boolean offer(E):添加元素到队尾;
  • E remove() / E poll():获取队首元素并从队列中删除;
  • E element() / E peek():获取队首元素但并不从队列中删除。
  • int size():获取队列大小。

对于具体的实现类,有的Queue有最大队列长度限制,有的Queue没有。注意到添加、删除和获取队列元素总是有两个方法,这是因为在添加或获取元素失败时,这两个方法的行为是不同的:

throw Exception返回false或null
添加元素到队尾add(E e)boolean offer(E e)
取队首元素并删除E remove()E poll()
取队首元素但不删除E element()E peek()

注意:不要把 null 添加到队列中,否则 poll() 方法返回 null 时,很难确定是取到了 null 元素还是队列为空。

Deque

Deque 接口继承自 Queue 接口

Queue 和 Deque 出队和入队的方法比较:

QueueDeque
添加元素到队尾add(E e) / offer(E e)addLast(E e) / offerLast(E e)
取队首元素并删除E remove() / E poll()E removeFirst() / E pollFirst()
取队首元素但不删除E element() / E peek()E getFirst() / E peekFirst()
添加元素到队首addFirst(E e) / offerFirst(E e)
取队尾元素并删除E removeLast() / E pollLast()
取队尾元素但不删除E getLast() / E peekLast()

Deque 接口实际上扩展自 Queue,因此,Queue 提供的 add()/offer() 方法在 Deque 中也可以使用,但是,使用 Deque,最好不要调用offer(),而是调用 offerLast()。即使用 Deque,推荐总是明确调用 offerLast() / offerFirst() 或者 pollFirst() / pollLast() 方法。

Deque 是一个接口,它的实现类有 ArrayDeque 和 LinkedList。

LinkedList,它即是List,又是Queue,还是Deque。但是我们在使用的时候,总是用特定的接口来引用它,这是因为持有接口说明代码的抽象层次更高,而且接口本身定义的方法代表了特定的用途。

// 不推荐的写法:
LinkedList<String> d1 = new LinkedList<>();// 推荐的写法:
Deque<String> d2 = new LinkedList<>();

可见面向抽象编程的一个原则就是:尽量持有接口,而不是具体的实现类。

总结

Deque实现了一个双端队列(Double Ended Queue),它可以:

  • 将元素添加到队尾或队首:addLast()/offerLast()/addFirst()/offerFirst();

  • 从队首/队尾获取元素并删除:removeFirst()/pollFirst()/removeLast()/pollLast();

  • 从队首/队尾获取元素但不删除:getFirst()/peekFirst()/getLast()/peekLast();

  • 总是调用xxxFirst()/xxxLast()以便与Queue的方法区分开;

  • 避免把null添加到队列。


Stack

栈(Stack)是一种后进先出(LIFO:Last In First Out)的数据结构,元素的插入和删除操作都发生在栈的顶端。虽然 Stack 类是 Java 提供的传统类,但它已被 Deque 接口的 ArrayDeque 替代,ArrayDeque 提供了更高效的栈操作。常见实现:Stack(遗留类,较旧,不推荐使用)、ArrayDeque推荐使用)。

Deque<String> stack = new ArrayDeque<>();

在Java中,我们用 Deque 可以实现 Stack 的功能:

  • 把元素压栈:push(E) / addFirst(E);

  • 把栈顶的元素“弹出”:pop() / removeFirst();

  • 取栈顶元素但不弹出:peek() / peekFirst()。

为什么 Java 的集合类没有单独的 Stack 接口呢?因为有个遗留类名字就叫 Stack,出于兼容性考虑,所以没办法创建 Stack 接口,只能用Deque 接口来“模拟”一个 Stack 了。

当我们把 Deque 作为 Stack 使用时,注意只调用 push() / pop() / peek() 方法,不要调用 addFirst() / removeFirst() / peekFirst() 方法,这样代码更加清晰。


Map(映射,存储键值对)

Map 是一个存储键值对(key-value)的集合,Map 中的键是唯一的,值可以重复。

实现类:

  • HashMap:基于哈希表实现,查找和插入的性能较高,元素无序。(HashMap 非线程安全,高效,支持null)

  • LinkedHashMap:保持插入顺序的 HashMap 实现。

  • TreeMap:基于红黑树实现,元素按键的自然顺序或指定的 Comparator 排序。

  • Hashtable:遗留类,过时的线程安全版本,不推荐使用。(HashTable 线程安全,低效,不支持null )

HashMap 是 Map 接口最常用的实现,基于哈希表实现。它在内部会对 Key 进行排序,这种 Map 就是 SortedMap。注意到 SortedMap 是接口,它的实现类是 TreeMap。

Map<String, String> map = new HashMap<>();

常用方法:

  • put(K key, V value):添加键值对。

  • get(Object key):根据键获取对应的值。

  • remove(Object key):删除指定键的键值对。

  • boolean containsKey(Object key):判断是否包含指定键。

  • containsValue(Object value):判断是否包含指定值。

  • keySet():获取所有键。

  • values():获取所有值。

PS: Map 中不存在重复的 key,因为放入相同的 key ,只会把原有的 key-value 对应的 value 给替换掉。

遍历 Map (无序,既不是插入顺序,也不是某个逻辑下的排序顺序)

for (String key : map.keySet()) {  // keySet()方法返回的Set集合,它包含不重复的key的集合Integer value = map.get(key);System.out.println(key + " = " + value);}for (Map.Entry<String, Integer> entry : map.entrySet()) {  // entrySet()集合,它包含每一个key-value映射String key = entry.getKey();Integer value = entry.getValue();System.out.println(key + " = " + value);
}

相关文章:

理解Java集合的基本用法—Collection:List、Set 和 Queue,Map

本博文部分参考 博客 &#xff0c;强烈推荐这篇博客&#xff0c;写得超级全面&#xff01;&#xff01;&#xff01; 图片来源 Java 集合框架 主要包括两种类型的容器&#xff0c;一种是集合&#xff08;Collection&#xff09;&#xff0c;存储一个元素集合&#xff08;单列…...

IOC容器实现分层解耦

文章开始之前&#xff0c;先引入软件开发的两个名词&#xff1a;耦合和内聚。耦合是指&#xff1a;衡量软件中各个层&#xff08;三层架构&#xff09;/各个模块的依赖关联程度&#xff1b;内聚是指&#xff1a;软件中各个功能模块内部的功能联系。三层架构中Controller、Servi…...

Flutter 共性元素动画

在 Flutter 中&#xff0c;共性元素动画&#xff08;Shared Element Transitions&#xff09;用于在页面导航或组件切换时创建视觉上更流畅和连贯的动画效果。这种动画可以使用户感受到两个界面之间的“物理联系”&#xff0c;比如图片从缩略图到全屏的扩大效果。 前置知识点整…...

K8s内存溢出问题剖析:排查与解决方案

文章目录 一、背景二、排查方案&#xff1a;1. 可能是数据量超出了限制的大小&#xff0c;检查数据目录大小2. 查看是否是内存溢出2.1 排查数据量&#xff08;查看数据目录大小是否超过limit限制&#xff09;2.2 查看pod详情发现问题 三、解决过程 一、背景 做redis压测过程中…...

乌班图单机(不访问外网)部署docker和服务的方法

面向对象:Ubuntu不能访问外网的机子,部署mysql、redis、jdk8、minio 过程: 1、安装docker(照着图去这里找对应的下载下来https://download.docker.com/linux/static/stable/),将7个docker官网下载的文件下载下来后,传上去服务器随便一个文件夹或者常用的opt或者/usr/lo…...

使用 pycharm 新建使用 conda 虚拟 python 环境的工程

1. conda 常见命令复习&#xff1a; conda env list // 查看 conda 环境列表 conda activate xxxenv // 进入指定 conda 环境2. 环境展示&#xff1a; 2.1. 我的物理环境的 Python 版本为 3.10.9&#xff1a; 2.2. 我的 conda 虚拟环境 env_yolov9_python_3_8 中的 pyth…...

Docker的save和export命令的区别,load和import的区别 笔记241124

Docker的save和export命令的区别,load和import的区别 解说1: Docker的save和export命令&#xff0c;以及load和import命令&#xff0c;在功能和使用场景上存在显著的区别。以下是对这两组命令的详细对比和解释&#xff1a; Docker save和export命令的区别 使用方式和目的&am…...

通俗理解人工智能、机器学习和深度学习的关系

最近几年人工智能成为极其热门的概念和话题&#xff0c;可以说彻底出圈了。但人工智能的概念在1955年就提出来了&#xff0c;可以说非常古老。我在上小学的时候《科学》课本上就有人工智能的概念介绍&#xff0c;至今还有印象&#xff0c;但那些年AI正处于“寒冬”&#xff0c;…...

使用 pycharm 新建不使用 python 虚拟环境( venv、conda )的工程

有时候我们发现一个好玩的 demo&#xff0c;想赶快在电脑上 pip install 一下跑起来&#xff0c;发现因为 python 的 venv、conda 环境还挺费劲的&#xff0c;因为随着时间的发展&#xff0c;之前记得很清楚的 venv、conda 的用法&#xff0c;不经常使用&#xff0c;半天跑不起…...

【大数据学习 | Spark-SQL】SparkSQL读写数据

我们使用sparksql进行编程&#xff0c;编程的过程我们需要创建dataframe对象&#xff0c;这个对象的创建方式我们是先创建RDD然后再转换rdd变成为DataFrame对象。 但是sparksql给大家提供了多种便捷读取数据的方式。 //原始读取数据方式 sc.textFile().toRDD sqlSc.createDat…...

AI赋能公共服务转型升级 | 第十届中国行业互联网大会暨腾讯云TVP行业大使三周年庆典公共服务专场圆满举办!

引言 党的二十大报告把“基本公共服务实现均等化”作为 2035 年我国发展的总体目标之一&#xff0c;强调要“健全基本公共服务体系&#xff0c;提高公共服务水平”。AI 作为新质生产力的核心驱动力之一&#xff0c;正在公共服务领域发挥着越来越重要的作用。 2024 年 10 月 2…...

关于按天切割Tomcat的catalina.out日志文件的配置

1、catalina.out 是 Tomcat 的标准输出和标准错误日志&#xff0c;通常输出到 Tomcat 安装目录下的 logs 文件夹中。这个日志文件会记录 Tomcat 启动、停止以及运行过程中产生的所有日志信息。 2、在Apache Tomcat中&#xff0c;日志文件catalina.out默认情况下不会自动按天切割…...

【人工智能】深入解析GPT、BERT与Transformer模型|从原理到应用的完整教程

在当今人工智能迅猛发展的时代&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域涌现出许多强大的模型&#xff0c;其中GPT、BERT与Transformer无疑是最受关注的三大巨头。这些模型不仅在学术界引起了广泛讨论&#xff0c;也在工业界得到了广泛应用。那么&#xff0c;G…...

彻底理解如何保证ElasticSearch和数据库数据一致性问题

一.业务场景举例 需求&#xff1a; 一个卖房业务&#xff0c;双十一前一天&#xff0c;维护楼盘的运营人员突然接到合作开发商的通知&#xff0c;需要上线一批热门的楼盘列表&#xff0c;上传完成后&#xff0c;C端小程序支持按楼盘的名称、户型、面积等产品属性全模糊搜索热门…...

2024-2025热门留学趋势

在信息爆炸的时代&#xff0c;留学已成为许多人规划未来、拓宽视野的重要途径。随着全球教育格局的不断变化&#xff0c;留学领域也涌现出一系列新热点和趋势。本文将为您解读2024年最热门的留学话题&#xff0c;并提供实用的准备策略&#xff0c;助您在留学之路上一帆风顺。 热…...

寻找视频特效素材的优质网站推荐 轻松提升作品魅力

在短视频、影视和广告制作中&#xff0c;视频特效素材已成为提升作品专业感的关键元素。炫酷的光效、震撼的爆炸、动感的粒子效果和流畅的转场特效&#xff0c;都能让作品更具吸引力。那么&#xff0c;视频特效素材去哪里找呢&#xff1f;今天&#xff0c;小编为大家精心挑选了…...

【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-36

文件下载与邀请翻译者 学习英特尔开发手册&#xff0c;最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。 讲解下载英特尔开发手册的文章 翻译英特尔开发手册&#xff0c;会是一件耗时费力的工作。如果有愿意和我一起来做这件事的&#xff0c;那么&#xff…...

信息安全实验--密码学实验工具:CrypTool

1. CrypTool介绍&#x1f4ad; CrypTool 1的开源教育工具&#xff0c;用于密码学研究。通过CrypTool 1&#xff0c;可以实现加密和解密操作&#xff0c;数字签名。CrypTool1和2有很多区别的。 2. CrpyTool下载&#x1f527; 在做信息安全实验--密码学相关实验时&#xff0c;发…...

python的class 类创建、方法调用以及属性赋值

题目&#xff1a;购物车系统 创建一个简单的购物车系统&#xff0c;要求如下&#xff1a; 定义一个 Product 类&#xff0c;表示商品&#xff0c;包含以下属性和方法&#xff1a; 属性&#xff1a; name&#xff1a;商品名称&#xff08;字符串&#xff09; price&#xff1…...

Angular v19 (二):响应式当红实现signal的详细介绍:它擅长做什么、不能做什么?以及与vue、svelte、react等框架的响应式实现对比

本文紧接着Angular v19 新版本来啦&#xff0c;一起瞧瞧新特性吧&#xff01;&#xff0c;主要针对它在v18引入了一项全新的响应式技术——Signal&#xff0c;这引起了开发者社区的广泛关注&#xff0c;最新的v19版本推出了更多的signal工具。Signal的加入旨在优化Angular的响应…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...