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

1️⃣Java中的集合体系学习汇总(List/Map/Set 详解)

目录

01. Java中的集合体系

02. 单列集合体系​

1. Collection系列集合的遍历方式

(1)迭代器遍历(2)增强for遍历​编辑(3)Lambda表达式遍历

 

03.List集合详解

04.Set集合详解

05.总结

Collection系列集合使用场景:​

集合的并发修改异常问题:①问题原因②解决办法


01. Java中的集合体系

Java中的集合分为两大类:

  • 单列集合(collection):添加数据时,一次只添加一个数据。数据带有下标

  • 双列集合(Map):在添加数据时,一次要添加一对数据;key和value(键值对)

02. 单列集合体系

单列集合起源于Collection接口,分为List集合和Set集合:

①List接口的三个实现类:ArrayList、LinkedList、Vector(现已弃用);

②List系列集合的特点有:有序、可重复、有索引,有序是指存入的顺序和取出时的顺序是相同的;

③Set接口有两个实现类:HashSet、TreeSet;

④Set系列集合的特点有:无序、不可重复、无索引,取数据时的顺序是随机的。

(1)单列集合顶层接口Collection

常用方法:

注意点:

1.添加元素 add 细节1: 如果我们要往List系列集合中添加数据, 那么方法永远返回true, 因为List系列的是允许元素重复的。 细节2: 如果我们要往Set系列集合中添加数据,如果当前要添加元素不存在,方法返回true,表示添加成功。 如果当前要添加的元素已经存在, 方法返回false,表示添加失败。因为Set系列的集合不允许重复。

2.删除 remove 细节1: 因为collection里面定义的是共性的方法, 所以此时不能通过索引 进行删除。 只能通过元素名称进行刷除。 细节2: 方法会有一个布尔类型的返回值, 删除成功返回true, 删除失败返回false,如果要除的元素不存在,就会删除失败。

4.判断元素是否包含 contain 细节:底层是依赖equals方法进行判断是否存在的。 所以,如果集合中存储的是自定义对象,也想通过contains方法来判断是否包含,那么在java Bean类中,一定要重写equals方法

源码查看方法: 方法一:选中contains()方法,Ctrl+B跟进,进入到Collection接口中的源码; 方法二:选中contains()方法,右键,选择Go to --> implements 然后选择对应的实现类

1. Collection系列集合的遍历方式

(1)迭代器遍历

迭代器Iterator简介:

代码示例:

//1.创建集合并添加元素
Collection<String> coll = new ArrayList<>();
​
coll.add("一");
coll.add("二");
coll.add("三");
coll.add("四");
coll.add("五");
coll.add("六");
​
//2.通过集合获取迭代器,迭代器就好比一个箭头,刚获取时默认指向集合首个元素
Iterator it = coll.iterator();
while (it.hasNext()){Object str = it.next();System.out.println(str);
}

迭代器使用注意点:

  • 当指针已经指向集合末尾时(如下图),继续调用next( )方法会报错误:NoSuchElementException

  • 迭代器遍历完毕后,指针不会自动复位;下次再遍历时需要再创建一个迭代器对象。

  • 在每次遍历中,next( )方法通常只调用一次,并用一个变量接收返回的元素;(因为每调用一次next( )方法,指针就会向后移动一位,所以每移动一次就要判断一下是否已经指向末尾了)

  • 迭代器遍历时,不能用集合的方法进行增加或删除。否则会引发并发修改异常:ConcurrentModificationException

那么如何在遍历集合时删除集合中元素呢?方法如下:

        使用Iterator.remove() 最安全和推荐的方法是使用迭代器的remove()方法,该方法专为遍历期间的安全删除设计。

List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {String element = iterator.next();if ("B".equals(element)) {iterator.remove();}
}
System.out.println(list); // 输出: [A, C]

优点:不抛异常,适用于多种集合(List、Set等)。

缺点:代码较为冗长,需要显式使用迭代器。

原文链接:java中如何在集合遍历过程中删除元素(5种方法对比、案例、常见的错误及其后果)_java集合删除元素-CSDN博客

(2)增强for遍历

        (小tips:在IDEA中快速打出增强for结构的写法:集合或数组名.for + Enter

        注意:增强for的底层是用迭代器实现的,在遍历时,也不能直接用集合的方法对元素进行增加或删除。否则会引发并发修改异常ConcurrentModificationException

(3)Lambda表达式遍历

 示例代码 :

 public static void main(String[] args) {Collection<Object> coll = new ArrayList<>();coll.add("张三");coll.add("李四");coll.add(456);coll.add(789);
​
//        for (Object o : coll) {
//            System.out.println(o);
//        }
​//常规写法coll.forEach(new Consumer<Object>() {@Overridepublic void accept(Object o) {System.out.println(o);}});
​//结合Lambda表达式写法coll.forEach((o) -> {System.out.println(o);});//再次简化coll.forEach(o->System.out.println(o));//结合方法引用,且前后参数一样时,再次简化coll.forEach(System.out::println);
​
​}

03.List集合详解

由于篇幅过长,为方便大家浏览,这部分内容单独开了一片博客:

Java基础进阶——List集合详解(看这一篇就够了,详解)-CSDN博客list集合属于Java集合体系中的单列集合,继承于父类Collection,如果你对Collection不了解,可以先看这篇文章1️⃣Java中的集合体系学习汇总(List/Map/Set 详解)-CSDN博客细节1: 如果我们要往List系列集合中添加数据, 那么方法永远返回true, 因为List系列的是允许元素重复的。细节2: 方法会有一个布尔类型的返回值, 删除成功返回true, 删除失败返回false,如果要除的元素不存在,就会删除失败。https://blog.csdn.net/Future_yzx/article/details/145159651?sharetype=blogdetail&sharerId=145159651&sharerefer=PC&sharesource=Future_yzx&spm=1011.2480.3001.8118

04.Set集合详解

Java基础进阶—Set集合详解(HashSet、LinkedHashset、TreeSet看这一篇就够了)-CSDN博客LinkedHashSet是HashSet实现类的子类,该集合中的数据是有序的(指添加数据的顺序和获取数据的顺序一致)TreeSet实现类,该集合具有排序功能,向其中存入的数据默认按升序的顺序排序Set系列集合常用方法基本都是父接口Collection提供的,没有特有方法。https://blog.csdn.net/Future_yzx/article/details/145160311?sharetype=blogdetail&sharerId=145160311&sharerefer=PC&sharesource=Future_yzx&spm=1011.2480.3001.8118

 05.总结

 

Collection系列集合使用场景:

 

集合的并发修改异常问题

  • 当我们使用迭代器遍历集合,并删除集合中某些数据时程序就会报错;
    (错误代码如下:)

    public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("张三");list.add("李四");list.add("王老二");list.add("王五");list.add("李逵");list.add("李世华");
    ​Iterator<String> it = list.iterator();while (it.hasNext()){String str = it.next();if (str.contains("李")){list.remove(str);}}
    }

程序报的异常:

Exception in thread "main" java.util.ConcurrentModificationException

如果我们不用迭代器,用普通for循环来进行相同操作也会有问题;
(错误示例代码:)

//用普通for循环来进行演示:
public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("张三");list.add("李四");list.add("李老二");list.add("王五");list.add("李逵");list.add("李世华");
​System.out.println("遍历前:"+list);
​for (int i = 0; i < list.size(); i++) {String s = list.get(i);if (s.contains("李")){list.remove(s);}}System.out.println("遍历后"+list);

输出结果:

遍历前:[张三, 李四, 李老二, 王五, 李逵, 李世华]

遍历后:[张三, 李老二, 王五, 李世华]

我们发现,程序并没有像我们预期的那样(将list集合内所有包含字符"李 "的元素删除掉);

①问题原因:

        当第一次遍历到元素"李四"时,程序会成功删除;由于ArrayList底层是数组实现的,删除元素后,后面元素会向前移动,这就导致下一个元素(李老二)会移动到当前索引的位置;然后i++,直接越过了对"李老二"的判断。

因此,在遍历集合时,每删除当前元素,就会跳过下一个元素的判断;

②解决办法:

●普通for循环的解决办法

①每次移除完数据以后,执行一次i--  ,示例代码:

for (int i = 0; i < list.size(); i++) {String s = list.get(i);if (s.contains("李")){list.remove(s);i--;//移除完数据后,执行i--}
}

②遍历时,改为从后往前遍历集合,示例代码:

for (int i = list.size()-1; i >= 0; i--) {//从后往前倒序遍历集合String s = list.get(i);if (s.contains("李")){list.remove(s);}
}

●使用迭代器的解决办法:用迭代器自带的remove方法来删除元素

Iterator<String> it = list.iterator();
while (it.hasNext()){String str = it.next();if (str.contains("李")){//list.remove(str);//会发生修改并发异常it.remove();//底层也相当于执行了一次i-- }
}

       

 最后,我们要注意:使用增强for 或 Lambda表达式的方法遍历时,也都会出现并发修改异常,且没有解决办法。

  • 因为增强for的的底层就是迭代器实现的,增强for就是迭代器的简化写法

相关文章:

1️⃣Java中的集合体系学习汇总(List/Map/Set 详解)

目录 01. Java中的集合体系 02. 单列集合体系​ 1. Collection系列集合的遍历方式 &#xff08;1&#xff09;迭代器遍历&#xff08;2&#xff09;增强for遍历​编辑&#xff08;3&#xff09;Lambda表达式遍历 03.List集合详解 04.Set集合详解 05.总结 Collection系列…...

闪豆多平台视频批量下载器

1. 视频链接获取与解析 首先&#xff0c;在哔哩哔哩网页中随意点击一个视频&#xff0c;比如你最近迷上了一个UP主的美食制作视频&#xff0c;想要下载下来慢慢学。点击视频后&#xff0c;复制视频页面的链接。复制完成后&#xff0c;不要急着关闭浏览器&#xff0c;因为接下来…...

深入解析:如何用Java爬取淘宝分类详情接口(cat_get)

一、前言 淘宝分类详情接口&#xff08;cat_get&#xff09;是淘宝开放平台提供的一个接口&#xff0c;允许开发者获取淘宝商品的分类详情&#xff0c;包括分类ID、分类名称、父分类等信息。这些数据对于电商分析、市场研究和商品分类管理等具有重要价值。本文将详细介绍如何使…...

语音识别的预训练模型

语音识别的预训练模型 语音识别模型 大致分为两类: 连接时序分类(Connectionist Temporal Classification, CTC):仅编码器(encoder-only)的模型,顶部带有线性分类(CTC)头序列到序列(Sequence-to-sequence, Seq2Seq):编码器-解码器(encoder-decoder)模型,编码器…...

element-ui制作多颜色选择器

将颜色存储到一个数组中去。 <template><div class"color-picker-container" style"margin-top: 10px;"><!-- 显示已选颜色 --><div class"color-selection"><divv-for"(color, index) in selectedColors"…...

JVM体系结构

目录 一. JVM 规范 二. JVM 实现 (1) HotSpot (2) JRockit (3) IBM JDK&#xff08;J9 VM&#xff09; (4) Azul Zing (5) OpenJ9 三. JVM 实现的选择 四. JVM 的核心组件 五.JVM总结 六.Java 虚拟机&#xff08;JVM&#xff09;架构概述 1.Java 虚拟机&#xff08…...

wandb使用遇到的一些问题

整合了一下使用wandb遇到的问题 1.请问下如果电脑挂了代理&#xff0c;应该怎么办呢&#xff1f;提示&#xff1a;Network error (ProxyError), entering retry loop. 在本地&#xff08;而非服务器&#xff09;运行代码时&#xff0c;常常因为开启代理而无法使用wandb&#…...

Java中的继承

引入继承 Java中使用类对实体进行描述&#xff0c;类经过实例化之后的产物对象&#xff0c;就可以用来表示现实中的实体&#xff0c;描述的事物错综复杂&#xff0c;事物之间可能会存在一些关联&#xff0c;因此我们就需要将他们共性抽取&#xff0c;面向对象的思想中提出了继…...

Cadence笔记--原理图导入PCB

1、以PMU6050为例&#xff0c;首先在原理图双击PMU6050器件&#xff0c;在PCB_Footprint目录填写PCB封装名称并且保存&#xff0c;如下图所示&#xff1a; 2、确保原理图命名的名称不一样&#xff0c;否则会出错&#xff0c;这里PMU6050更改了NC等名称&#xff0c;如下图所示&a…...

从AI生成内容到虚拟现实:娱乐体验的新边界

引言 在快速发展的科技时代&#xff0c;娱乐行业正经历一场前所未有的变革。传统的娱乐方式正与先进技术融合&#xff0c;创造出全新的沉浸式体验。从AI生成的个性化内容&#xff0c;到虚拟现实带来的身临其境的互动场景&#xff0c;科技不仅改变了我们消费娱乐的方式&#xf…...

【Linux】gdb_进程概念

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…...

安全类脚本:拒绝ssh暴力破解

要求如下&#xff1a; 一个小时内&#xff0c;连续密码错误4次。 Linux lastb 命令用于列出登入系统失败的用户相关信息。 实验过程如下&#xff1a; 1. 创建两个IP地址不同的干净环境&#xff0c;分别是&#xff1a;192.168.46.101 Rocky 2 和 192.168.46.120 openEuler 2. 2.…...

Android15源码编译问题处理

最近想在Raspberry Pi5上面运行自己编译的Android15镜像,参考如下链接来处理: GitHub - raspberry-vanilla/android_local_manifest GitHub - raspberry-vanilla/android_kernel_manifest 代码同步完后,编译就出问题了,总是提示: FAILED: analyzing Android.bp files and…...

图解Git——分布式Git《Pro Git》

分布式工作流程 Centralized Workflow&#xff08;集中式工作流&#xff09; 所有开发者都与同一个中央仓库同步代码&#xff0c;每个人通过拉取、提交来合作。如果两个开发者同时修改了相同的文件&#xff0c;后一个开发者必须在推送之前合并其他人的更改。 Integration-Mana…...

Linux内核编程(二十一)USB应用及驱动开发

一、基础知识 1. USB接口是什么&#xff1f; USB接口&#xff08;Universal Serial Bus&#xff09;是一种通用串行总线&#xff0c;广泛使用的接口标准&#xff0c;主要用于连接计算机与外围设备&#xff08;如键盘、鼠标、打印机、存储设备等&#xff09;之间的数据传输和电…...

什么是数据仓库?

什么是数据仓库&#xff1f; 数据仓库&#xff08;Data Warehouse&#xff0c;简称DW&#xff09;是一种面向分析和决策的数据存储系统&#xff0c;它将企业中分散的、异构的数据按照一定的主题和模型进行集成和存储&#xff0c;为数据分析、报表生成以及商业智能&#xff08;…...

计算机网络 (48)P2P应用

前言 计算机网络中的P2P&#xff08;Peer to Peer&#xff0c;点对点&#xff09;应用是一种去中心化的网络通信模式&#xff0c;它允许设备&#xff08;或节点&#xff09;直接连接并共享资源&#xff0c;而无需传统的客户端-服务器模型。 一、P2P技术原理 去中心化架构&#…...

SK海力士(SK Hynix)是全球领先的半导体制造商之一,其在无锡的工厂主要生产DRAM和NAND闪存等存储器产品。

SK海力士&#xff08;SK Hynix&#xff09;是全球领先的半导体制造商之一&#xff0c;其在无锡的工厂主要生产DRAM和NAND闪存等存储器产品。以下是SK海力士的一些主要产品型号和类别&#xff1a; DRAM 产品 DDR4 DRAM 特点: 高速、低功耗&#xff0c;广泛应用于PC、服务器和移…...

FunASR 在Linux/Unix 平台编译

第一步拉取镜像并生成容器&#xff1a; ### 镜像启动 通过下述命令拉取并启动FunASR软件包的docker镜像&#xff1a; shell sudo docker pull \ registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.12 mkdir -p ./funasr-runtime-…...

git操作(Windows中GitHub)

使用git控制GitHub中的仓库版本&#xff0c;并在Windows桌面中创建与修改代码&#xff0c;与GitHub仓库进行同步。 创建自己的GitHub仓库 创建一个gen_code实验性仓库用来学习和验证git在Windows下的使用方法&#xff1a; gen_code仓库 注意&#xff0c;创建仓库时不要设置…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...