【 java 集合知识 第一篇 】

1.概念

1.1.集合与数组的区别

集合:长度不固定,动态的根据数据添加删除改变长度,并且只能存入引用类型,读取采用迭代器或其他方法

数组:长度固定,不可改变,既可以存入基本类型也可以存入引用类型,读取使用索引读(for)

长度存入类型读取
集合长度不固定,动态的根据数据添加删除改变长度只能存入引用类型采用迭代器或其他方法
数组长度固定,不可改变既可以存入基本类型也可以存入引用类型使用索引(for)

1.2.集合分类

分为三类:List类,Set类,Map类

List集合:集合里面元素有序,并且允许可重复

Set集合:集合里面元素无序,并且不可重复(保证唯一性)

Map集合:集合采用键值对方式,key唯一(不允许重复)无序,value没有要求

是否有序是否可重复
List有序可重复
Set无序不可重复

1.3.Collection和Collections的区别

Collection是一个接口,给集合实现的,里面定义了一些操作集合的方法

Collections是一个工具类,位于java.util包中,可以直接使用该类操作集合(增删改,排序)

1.4.集合遍历的方法

有六种方法:for,增强for,迭代器,列表迭代器,foeEach,Stream流

for:带索引查询(区分集合是否带索引,才能使用该方法)

List<String> list = Arrays.asList("A", "B", "C");// 通过索引遍历(适合 ArrayList 等支持随机访问的集合)
for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));
}

增强for:没有索引,直接遍历查询

List<String> list = Arrays.asList("A", "B", "C");// 直接遍历元素(底层基于迭代器实现)
for (String item : list) {System.out.println(item);
}

迭代器:在迭代器里面只能删除元素,不能插入元素

List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> iterator = list.iterator();// 通过迭代器遍历(适用于所有 Collection)
while (iterator.hasNext()) {String item = iterator.next();System.out.println(item);// 可在遍历中安全删除元素:iterator.remove();
}
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {String item = iterator.next();if ("B".equals(item)) {iterator.remove(); // 允许删除当前元素// iterator.add("D"); // 编译错误:Iterator 没有 add() 方法}
}

列表迭代器:没有限制,可以进行删除查询插入元素

List<String> list = Arrays.asList("A", "B", "C");
ListIterator<String> listIterator = list.listIterator();// 正向遍历(从头到尾)
while (listIterator.hasNext()) {String item = listIterator.next();System.out.println(item);
}// 反向遍历(从尾到头)
while (listIterator.hasPrevious()) {String item = listIterator.previous();System.out.println(item);
}
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
ListIterator<String> listIterator = list.listIterator();// 正向遍历
while (listIterator.hasNext()) {String item = listIterator.next();if ("B".equals(item)) {listIterator.remove();  // 删除当前元素listIterator.add("D");  // 在当前位置插入新元素listIterator.set("E");  // 替换当前元素(需在 next() 或 previous() 后调用)}
}// 反向遍历
while (listIterator.hasPrevious()) {String item = listIterator.previous();System.out.println(item);
}

forEach:因为它基于迭代器实现的,因此也不能在循环中插入元素

List<String> list = Arrays.asList("A", "B", "C");// 使用 Lambda 表达式遍历
list.forEach(item -> System.out.println(item));// 或使用方法引用
list.forEach(System.out::println);

Stream:没有限制

List<String> list = Arrays.asList("A", "B", "C");// 转换为 Stream 并遍历
list.stream().forEach(item -> System.out.println(item));// 并行流遍历(多线程处理)
list.parallelStream().forEach(item -> System.out.println(item));

2.List

2.1.List的实现

实现List的集合有:ArrayList,LinkedList,Vector

ArrayList:基于动态的数组创建的,查询效率高,增删效率一般,线程不安全

LinkedList:基于双向链表创建的,查询效率一般,增删效率高,线程不安全

Vector:基于动态数组创建的,与ArrayList类似,不过它是线程安全的

数据结构读操作写操作线程安全
ArrayList数组一般不安全
LinkedList双向链表一般不安全
Vector数组一般安全

2.2.可以一边遍历一边修改List的方法

首先思考有几个遍历方法:六个

哪些是不能修改元素的:迭代器,forEach

最终得到的方法:for,增强for,列表迭代器,Stream流

2.3.List快速删除元素的原理

原理是基于集合底层数据结构不同,分为两类:ArrayList,LinkedList

ArrayList:基于数组对吧,原先数组是通过索引删除数据,那么因此ArrayList也是如此,基于索引来删除数据

具体实现:如果你是删除尾部最后一个数据,直接删除即可,时间复杂度为O(1),如果不是,那么它会将索引元素删除后,将后面的元素往前面覆盖,然后计算出集合长度,时间复杂度为O(n),n为元素的个数

LinkedList:基于双向链表,简单来说链表由节点组成,每个节点包含自己的数据与前一个节点的引用和后一个节点的引用,实现双向并通

具体实现:如果你是删除尾部最后一个数据,直接删除即可,时间复杂度为O(1),如果不是,那么就是从头或尾进行查询删除,时间复杂度O(n)

2.4.ArrayList与LinkedList的区别

  • 数据结构组成不同:Array List基于数组,LinkedList基于双向链表
  • 删除和插入效率不同:ArrayList在尾部的效率高(平均O(1)),在其他的地方效率低,由于需要进行元素覆盖,而LinkedList它基于链表引用,在尾部的效率(O(1)比ArrayList效率低(ArrayList基于数组,内存是连续的,而LinkedList基于链表,内存不连续),在其他地方删除与插入与ArrayList效率差不多(O(n))
  • 随机访问速度:由于ArrayList基于数组根据索引查询,时间复杂度O(1),而LinkedList基于链表,它需要从头或尾部访问,因此时间复杂度为O(n)
  • 适用场景不同:ArrayList更适合高频的随机访问操作或尾部插入为主,LinkedList更适合高频头尾插入/删除(队列)或需要双向遍历
  • 线程安全:都是线程不安全的

2.5.线程安全

实现线程(List)安全的方法有:

  • 实现Collections.synchronizedList,将线程不安全的List集合加个锁,变成安全的
  • 直接使用线程安全的List集合:比如Vector,CopyOnWirteArrayList

2.6.ArrayList的扩容机制

首先如果你没有指定长度,默认长度为10,当你要添加元素并且超过此时容量长度时,就会进行扩容操作

实现:

1.扩容:创建一个新的数组,新数组的长度为原数组的1.5倍数,然后再检查容量是否足够,不够继续扩容

---

2.复制:将旧的数组里面的值复制进新的数组中,再进行写操作

---

3.更改引用:将原先指向旧数组的引用指向新数组

---

4.扩容完成:可以继续扩容

2.7.CopyOnWirteArrayList

它实现了读写分离,写操作加了互斥锁ReentrantLock,避免出现线程安全问题,而读操作没有加锁,使用volatile关键字修饰数组,保证当前线程对数组对象重新赋值后,其他线程可以及时感知到(所有线程可见性)。线程读取数据可以直接读取,提高效率

写操作:它不会向ArrayList一样直接扩容1.5倍,它是根据你的添加元素个数多少来扩容,如果你只添加一个元素,那么它会创建一个新数组,长度比旧数组长度多一,然后依旧是依次复制元素进新数组中,改变内部引用指向(需要频繁创建新的数组,以时间换空间)

读操作:就是说它不会管你的数据是否修改,内部指向是旧数组,那么就读取旧数组的数据,指向是新数组就读取新数据,这样效率会高(数据弱一致性)

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

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

相关文章

嵌入式开发学习日志(linux系统编程--系统编程之 进程间通信IPC)Day32

一、引言 空间独立&#xff0c;需要一些操作&#xff1b; 分为三大类&#xff1a; 1、古老的通信方式 无名管道 有名管道 信号 2、IPC对象通信 system v BSD suse fedora kernel.org 消息队列(用的相对少&#xff0c;这里不讨论) …

metersphere不同域名的参数在链路测试中如何传递?

域名1&#xff1a;https://api.domain1.com 域名2&#xff1a;https://api.domain2.com 域名1的返回参数stteid会作为域名2的入参 步骤&#xff1a; 1&#xff09;先在metersphere—接口测试—接口定义中创建域名1和域名2的接口 2&#xff09;接口创建好后&#xff0c;在接口测…

使用Process Explorer、System Informer(Process Hacker)和Windbg工具排查软件高CPU占用问题

目录 1、问题现象 2、使用Process Explorer和System Informer&#xff08;该工具原先叫Process Hacker&#xff09;查看占用CPU高的线程 3、使用System Informer工具时发现了一个关键细节 4、将Windbg附加到软件进程上&#xff0c;根据System Informer中显示的线程id到Wind…

Linux(线程概念)

目录 一 虚拟地址到物理地址的转换 1. 操作系统如何管理物理内存&#xff1a; 2. 下面来谈谈虚拟地址如何转换到物理地址&#xff1a; 3. 补充字段&#xff1a; 二 Linux中的线程 1. 先来说说进程&#xff1a; 2. 线程&#xff1a; 3. 线程相比较于进程的优缺点&#x…

阿里云为何,一个邮箱绑定了两个账号

阿里云“幽灵账号”之谜&#xff1a;同一个邮箱注销后仍有两个账号&#xff1f;深度揭秘成因与终极解决方案&#xff01; 你是否曾在阿里云上使用同一个邮箱注册过多个账号&#xff0c;明明已经**“彻底”注销了其中一个**&#xff0c;却惊愕地发现系统里依然**“幽灵般”挂着…

动态规划-数位DP

今天开始做关于数位DP的问题&#xff0c;首先对于数位DP来说&#xff0c;这类问题难度较大&#xff0c;比较难理解&#xff0c;所以博主也会尽量讲的更加详细一些&#xff0c;来帮助大家更好地理解这里的相关知识。 前置知识&#xff1a; 1.首先对于数位DP来说&#xff0c;主…

总览四级考试

别被“四级”这个庞然大物吓到&#xff01;我们一起拆解它&#xff1a;​​ &#x1f4cd; ​​核心认知&#xff1a;四级是一场策略性考试&#xff01;​​ 它不考智商&#xff0c;考的是​​基础英语能力 考试技巧 时间管理​​。基础可以通过努力补&#xff0c;技巧可以…

BSRR对比BRR对比ODR

✅ 三种操作方式的本质区别 寄存器功能原子操作特点BSRR同时支持置位(1)和复位(0)✔️ 是单指令完成任意位操作&#xff0c;无竞争风险ODR直接读写输出状态❌ 否需"读-改-写"&#xff0c;多线程/中断中需关中断保护BRR只能复位(0)✔️ 是仅清零功能&#xff0c;无置…

职坐标精选嵌入式AI物联网开源项目

随着嵌入式、AI与物联网技术的深度融合&#xff0c;开源生态已成为开发者构建智能硬件解决方案的核心驱动力。本文将从嵌入式实时操作系统、多模态AI数据集及物联网接入平台三大维度切入&#xff0c;系统性梳理技术选型要点与实践路径。在嵌入式领域&#xff0c;重点解析低功耗…

Ubuntu系统 | 本地部署ollama+deepseek

1、Ollama介绍 Ollama是由Llama开发团队推出的开源项目,旨在为用户提供高效、灵活的本地化大型语言模型(LLM)运行环境。作为Llama系列模型的重要配套工具,Ollama解决了传统云服务对计算资源和网络连接的依赖问题,让用户能够在个人电脑或私有服务器上部署和运行如Llama 3等…

【数据库】关系数据库标准语言-SQL(金仓)下

4、数据查询 语法&#xff1a; SELECT [ALL | DISTINCT] <目标列表达式> [,<目标列表达式>] … FROM <表名或视图名>[, <表名或视图名> ] … [ WHERE <条件表达式> ] [ GROUP BY <列名1> [ HAVING <条件表达式> ] ] [ ORDER BY <…

基于YOLO-NAS-Pose的无人机象群姿态估计:群体行为分析的突破

【导读】 应对气候变化对非洲象的生存威胁&#xff0c;本研究创新采用无人机航拍结合AI姿态分析技术&#xff0c;突破传统观测局限。团队在肯尼亚桑布鲁保护区对比测试DeepLabCut与YOLO-NAS-Pose两种模型&#xff0c;首次将后者引入野生动物研究。通过检测象群头部、脊柱等关键…

8.RV1126-OPENCV 视频中添加LOGO

一.视频中添加 LOGO 图像大体流程 首先初始化VI,VENC模块并使能&#xff0c;然后创建两个线程&#xff1a;1.把LOGO灰度化&#xff0c;然后获取VI原始数据&#xff0c;其次把VI数据Mat化并创建一个感兴趣区域&#xff0c;最后把LOGO放感兴趣区域里并把数据发送给VENC。2.专门获…

AI+3D 视觉重塑塑料袋拆垛新范式:迁移科技解锁工业自动化新高度

在工业自动化浪潮席卷全球的当下&#xff0c;仓储物流环节的效率与精准度成为企业降本增效的关键战场。其中&#xff0c;塑料袋拆垛作为高频、高重复性的作业场景&#xff0c;传统人工或机械臂操作面临着诸多挑战。迁移科技&#xff0c;作为行业领先的 3D 工业相机和 3D 视觉系…

MATLAB实战:视觉伺服控制实现方案

以下是一个基于MATLAB的视觉伺服控制项目实现方案&#xff0c;结合实时图像处理、目标跟踪和控制系统设计。我们将使用模拟环境进行演示&#xff0c;但代码结构可直接应用于真实硬件。 系统架构 图像采集 → 目标检测 → 误差计算 → PID控制器 → 执行器控制 完整代码实现 …

RequestRateLimiterGatewayFilterFactory

一、功能说明 RequestRateLimiterGatewayFilterFactory 是 Spring Cloud Gateway 的流量控制组件&#xff0c;用于实现 API 请求速率限制&#xff0c;核心功能包括&#xff1a; 限制单位时间内的请求数量&#xff08;如每秒10次&#xff09;防止服务被突发流量击垮&#xff0…

鸿蒙仓颉语言开发实战教程:购物车页面

大家上午好&#xff0c;仓颉语言商城应用的开发进程已经过半&#xff0c;不知道大家通过这一系列的教程对仓颉开发是否有了进一步的了解。今天要分享的购物车页面&#xff1a; 看到这个页面&#xff0c;我们首先要对它简单的分析一下。这个页面一共分为三部分&#xff0c;分别是…

AXURE安装+汉化-Windows

安装网站&#xff1a;https://www.axure.com/release-history/rp9 Axure中文汉化包下载地址 链接:https://pan.baidu.com/s/1U62Azk8lkRPBqWAcrJMFew?pwd5418 提取码:5418 下载完成之后&#xff0c;crtlc lang文件夹 到下载的Axure路径下 双击点进这个目录里面。ctrlv把lan…

【Oracle】视图

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 视图基础概述1.1 视图的概念与特点1.2 视图的工作原理1.3 视图的分类 2. 简单视图2.1 创建简单视图2.1.1 基本简单视图2.1.2 带计算列的简单视图 2.2 简单视图的DML操作2.2.1 通过视图进行INSERT操作2.2.2 通…

Lua和JS的垃圾回收机制

Lua 和 JavaScript 都采用了 自动垃圾回收机制&#xff08;GC&#xff09; 来管理内存&#xff0c;开发者无需手动释放内存&#xff0c;但它们的 实现机制和行为策略不同。下面我们从原理、策略、优缺点等方面来详细对比&#xff1a; &#x1f536; 1. 基本原理对比 特性LuaJa…