系列十三、集合

一、集合

1.1、概述

        集合与数组类似,只不过集合中的数据量可以动态的变化。

1.2、体系图

1.3、List集合

1.3.1、特点

        存放的数据可以重复且有序。

1.3.2、常见操作

/**
 * List集合常见操作
 * 
 */
@Test
public void listOperateTest() {
	List<String> cityList = new ArrayList<>(4);
	// 添加元素
	cityList.add("beijing");
	cityList.add("shanghai");
	cityList.add("guangzhou");
	cityList.add("shenzhen");

	// 获取集合中的某一个元素
	System.out.println("============================");
	String element = cityList.get(0);
	System.out.println("element = " + element);

	// 获取集合中的所有元素
	System.out.println("============================");
	System.out.println("所有元素:" + cityList);

	// 集合的长度
	System.out.println("============================");
	System.out.println("集合的长度:" + cityList.size());

	// 判断某个元素是否在集合中
	System.out.println("============================");
	boolean exist = cityList.contains("beijing");
	System.out.println("元素是否存在于集合中:" + exist);

	// 删除集合中的某个元素
	System.out.println("============================");
	System.out.println("删除之前:" + cityList);
	boolean remove = cityList.remove("beijing");
	System.out.println("删除结果:" + remove);
	System.out.println("删除之后:" + cityList);
}

1.3.3、ArrayList vs LinkedList

(1)ArrayList底层是数组,LinkedList底层是链表;

(2)ArrayList查询快、增删慢;LinkedList增删快、查询慢;

1.4、Set集合

1.4.1、特点

        存放的数据不能重复,无序。

1.4.2、常见操作

/**
 * Set集合常见操作
 */
@Test
public void setOperateTest() {
	HashSet<String> countrySet = new HashSet<>(4);
	// 添加元素
	countrySet.add("中国");
	countrySet.add("中国");
	countrySet.add("美国");
	countrySet.add("日本");

	// 查询所有元素
	System.out.println("====================");
	System.out.println("查询所有元素:" + countrySet);

	// 修改[删除]数据
	System.out.println("====================");
	boolean removeResult = countrySet.remove("日本");
	System.out.println("删除结果 = " + removeResult);
	boolean addResult = countrySet.add("德国");
	System.out.println("添加结果 = " + addResult);
	System.out.println("修改后的数据:" + countrySet);

	// 查询集合中元素的个数
	System.out.println("====================");
	System.out.println("查询集合中元素的个数:" + countrySet.size());

	// 遍历Set
	System.out.println("====================");
	for (String country : countrySet) {
		System.out.print(country + "\t");
	}
}

1.4.3、HashSet vs TreeSet

        HashSet的底层是哈希表、TreeSet的底层是二叉树。

1.5、Map集合

1.5.1、概述

        前面介绍的List、Set集合是单列集合,而Map是双列集合。

1.5.2、常见操作

/**
 * Map常见操作
 */
@Test
public void mapOperateTest() {
	Map<String, Object> map = new HashMap<>();
	// 添加元素:key-value、key必须唯一,不能重复!
	map.put("name", "李白");
	map.put("idNum", "411528199801012656");
	map.put("cardNo", "622202170205888999");
	map.put("email", "libai@qq.com");

	// 查询所有元素
	System.out.println("=======================");
	System.out.println("查询所有元素:" + map);

	// 根据key获取value
	System.out.println("=======================");
	Object value = map.get("name");
	System.out.println("根据key获取value:" + value);

	// 修改元素
	System.out.println("=======================");
	Object updateResult = map.put("name", "李太白");
	System.out.println("修改结果:" + updateResult);
	System.out.println("修改后集合中所有的元素:" + map);

	// 集合中元素的个数
	System.out.println("=======================");
	int size = map.size();
	System.out.println("集合中元素的个数:" + size);

	// 删除元素
	System.out.println("=======================");
	Object removeResult = map.remove("email");
	System.out.println("删除结果:" + removeResult);
	System.out.println("删除后集合中所有的元素:" + map);

	// 判断某个元素是否在集合中
	System.out.println("=======================");
	boolean keyExist = map.containsKey("idNum");
	boolean valueExist = map.containsValue("411528199801012656");
	log.info("key是否存在:{},value是否存在:{}", keyExist, valueExist);


	// 遍历集合
	System.out.println("=======================");
	for (Map.Entry<String, Object> entry : map.entrySet()) {
		System.out.println(entry.getKey() + ":" + entry.getValue());
	}
}

 

 二、集合相关的面试题

2.1、说一说Java中常见的集合

        Java中提供了大量的集合类,主要分为两大类,即:单列集合和双列集合,下面详细介绍:

第一个是Collection 属于单列集合,第二个是Map 属于双列集合。

在Collection中有两个子接口List和Set。在我们平常开发的过程中用的比较多像list接口中的实现类ArrarList和LinkedList。 在Set接口中有实现类HashSet和TreeSet。
在map接口中有很多的实现类,平时比较常见的是HashMap、TreeMap,还有一个线程安全的map:ConcurrentHashMap

2.2、List集合是如何扩容的

2.2.1、源码(部分)

2.2.2、详解

        ArrayList是一个数组结构的存储容器,默认情况下数组的长度是10个,当然我们也可以在构建ArrayList对象的时候指定初始长度,那么随着程序不断的往集合中添加元素,当添加的元素达到10个的时候,ArrayList里面就没有足够的容量来存储新的元素了,那么这个时候ArrayList就会触发自动扩容,扩容的流程大致如下:

(1)创建一个新的数组,那么这个数组的长度是原来的1.5倍;

(2)使用Arrays.copyOf()方法将老的数据拷贝到新的数组里面,接着再把当前需要添加的元素添加到当前数组里面,从而完成动态扩容的一个过程;

2.3、HashMap是如何扩容的

2.3.1、源码(部分)

2.3.2、详解

        当我们在创建一个集合对象的时候,实际上就是在内存里面一次性申请了一块内存空间,而这个内存空间的大小是在创建集合对象的时候指定的,对于Map集合而言,默认的初始大小为16,在实际开发中,随着不断的往集合中添加元素,会导致集合的容量不够,这个时候就会触发集合的自动扩容,那么具体是怎么扩容的呢?当集合中的元素达到某个阈值的时候,Map集合就会进行动态扩容,阈值的计算公式为:16 * 0.75 = 12,即默认情况下,当Map集合中的元素达到12的时候,将会触发Map容器的自动扩容机制,从而更好的满足存储更多数据的需求,也即当Map中元素的个数达到12的时候,将会触发第一次扩容,扩容后容器的容量变为原来的2倍,即32;第二次扩容的临界值为:32 * 0.75 = 24,即当Map集合中元素的个数达到24的时候,将会触发第二次扩容;其他依次类推...

        所以,当我们在创建集合对象的时候,要充分考虑集合中所存储元素的个数,防止容器频繁的扩容,影响系统的性能。

2.3.3、为什么扩容因子是0.75

        扩容因子表示hash表中元素的填充程度,扩容因子的值越大,那么就意味着触发扩容元素的个数会更多,虽然它的整体空间利用率比较高,但是hash冲突的概率也会随之增加,反过来说扩容因子的值越小,那么触发扩容元素的个数也就越小,hash冲突的概率也越小,但是对于内存空间的浪费就比较多了,而且还会增加扩容的频率,影响系统的性能,因此扩容因子值的设置,不宜过大也不宜过小。0.75这个值的来源和统计学里面的【泊松分布】有关系,HashMap里面是采用链式寻址的方式去解决hash冲突的,而为了避免链表过长带来的一个时间复杂度增加的情况,所以当链表的长度大于等于7的时候就会转化成红黑树,从而提升检索的效率,当扩容因子在0.75的时候,链表长度达到8的可能性几乎为0,也就是说负载因子设置为0.75比较好的达到了空间成本和时间成本的一个平衡。

2.4、HashSet是如何保证元素不重复的

2.4.1、概述

        前面的内容介绍了HashSet,它和其他单列集合一个显著的区别就是元素不重复,那么它是如何实现元素不重复的呢?

2.4.2、源码(部分)

构造方法:

add方法:

 

         

 

2.4.3、分析

        从源码可以看出,HashSet的内部其实是利用了HashMap来实现的,内部持有一个HashMap的引用,操作HashSet实际上底层是操作这个map,HashMap的key是唯一的,从上面的源码可以看出HashSet添加进去的值其实是作为HashMap的key,所以HashSet中的元素不会重复。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

1.9 day7 IO进程线程

使用消息队列完成两个进程间的通信 进程1 #include <myhead.h> struct migbuf {long a;//消息类型char b[1024];//消息正文 }; #define SIZE (sizeof(struct migbuf)-sizeof(long)) int main(int argc, const char *argv[]) {//创建key值key_t key0;if((keyftok(".…

【算法Hot100系列】下一个排列

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

conda新建、配置python3.8虚拟环境,torch-cuda1.8,torchtext0.9.0,huggingface安装transformers库

起因是我在用bert的时候&#xff0c;导包报错 Python 环境缺少 importlib.metadata 模块。importlib.metadata 是 Python 3.8 引入的模块&#xff0c;而我的环境中使用的 Python 版本为 3.7。所以我得重新配置一个python3.8的环境 准备工作 在开始菜单找到anaconda prompt(an…

mongodb学习篇

目录 前言基本概念数据库-database集合-collection文档-document 部署mongodblinux安装mongodbdocker安装mongodb MongoDB Shell (mongosh)命令行工具mongodb可视化-mongodb-compass、mongo-expressmongodb配置文件mongodb库、集合、文档库基本操作集合基本操作文档的增删改查C…

springBoot-自动配置原理

以下笔记内容&#xff0c; 整理自B站黑马springBoot视频&#xff0c;抖音Holis 1、自动配置原理 1.收集Spring开发者的编程习惯&#xff0c;整理开发过程使用的常用技术列表一>(技术集A) 2.收集常用技术(技术集A)的使用参数&#xff0c;整理开发过程中每个技术的常用设置列表…

关于Js深拷贝的三种方法详细讲解

目录 前言 一、pandas是什么&#xff1f; 二、使用步骤 1.利用函数递归来实现深拷贝 2.利用引入lodash包 3.利用JSON字符串转换 总结 前言 当涉及到JavaScript数据拷贝的时候&#xff0c;深拷贝是一个非常关键的概念。在JavaScript中&#xff0c;对象和数组被认为是引用类型&a…

我在工作一年时怎么都看不懂的编程写法。今天手把手教给你

作为一名程序员&#xff0c;你一定遇到或亲自写过这样的代码。有人将它形象的形容为shi山&#xff0c;或者被戏称为“面向保就业编程”。 以下面这个代码为例&#xff0c;其中的问题也显而易见&#xff0c;当越来越多的条件判断时&#xff0c;代码会变得非常臃肿&#xff0c;难…

Minecraft教程:使用MCSM面板搭建我的世界私服并实现远程联机

文章目录 前言1. 安装JAVA2. MCSManager安装3.局域网访问MCSM4.创建我的世界服务器5.局域网联机测试6.安装cpolar内网穿透7. 配置公网访问地址8.远程联机测试9. 配置固定远程联机端口地址9.1 保留一个固定tcp地址9.2 配置固定公网TCP地址9.3 使用固定公网地址远程联机 前言 Li…

学习笔记之——3D Gaussian Splatting及其在SLAM与自动驾驶上的应用调研

之前博客介绍了NeRF-SLAM&#xff0c;其中对于3D Gaussian Splatting没有太深入介绍。本博文对3D Gaussian Splatting相关的一些工作做调研。 学习笔记之——NeRF SLAM&#xff08;基于神经辐射场的SLAM&#xff09;-CSDN博客文章浏览阅读967次&#xff0c;点赞22次&#xff0…

【野火i.MX6ULL开发板】在MobaXterm平台利用Type-C线串口连接开发板

0、前言 参考文献&#xff1a; http://t.csdnimg.cn/9iRTm http://t.csdnimg.cn/Z0n60 问题&#xff1a;一直识别不出com口&#xff0c; 拟解决思路&#xff1a; 百度网盘重新下载Debian镜像&#xff0c;烧入full版镜像&#xff0c;随便换一下USB插口&#xff08;电脑主机上…

EI级 | Matlab实现VMD-TCN-GRU变分模态分解结合时间卷积门控循环单元多变量光伏功率时间序列预测

EI级 | Matlab实现VMD-TCN-GRU变分模态分解结合时间卷积门控循环单元多变量光伏功率时间序列预测 目录 EI级 | Matlab实现VMD-TCN-GRU变分模态分解结合时间卷积门控循环单元多变量光伏功率时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.【EI级】Matlab实现…

图片纹理贴图

/* * 当需要给图形赋予真实颜色的时候&#xff0c;不太可能为没一个顶点指定一个颜色&#xff0c;通常会采用纹理贴图 * 每个顶点关联一个纹理坐标 (Texture Coordinate) 其它片段上进行片段插值 * */#include <iostream> #define STBI_NO_SIMD #define STB_IMAGE_IMPLE…

【Docker】Docker基础

文章目录 安装使用帮助启动命令镜像命令容器命令 安装 # 卸载旧版本 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine # 设置存储库 sudo yum install -y yum-utils …

数据结构与算法(十)深度优先搜索与广度优先搜索

广度优先搜索 广度优先搜索&#xff1a;从一个顶点出发&#xff08;由开始时顶点创造顺序优先决定&#xff09;&#xff0c;访问所有没有被访问过的临节点。然后在从被访问过的节点出发&#xff0c;重复之前的操作 如下为一个图 从1出发&#xff0c;先后访问2 3&#xff0c;之后…

VMware复制粘贴共享文件夹

win和虚拟机之间&#xff0c;无法复制粘贴&#xff0c;共享文件夹的解决方案。 安装VMware tools 1&#xff0c;先检查虚拟机设置部分。共享文件夹已启用。复制粘贴已启用。 2&#xff0c;安装tools.选择重新安装VMware tools. (此图片为安装过的截图) 成功后会显示如图。…

C++的一些书籍整理(个人学习)

UNIX环境高级编程&#xff08;第三版&#xff09; UNXI网络编程卷1 网络编程的笔记 收藏 我会了 一堆书 这个仓 数据库连接池原理介绍常用连接池介绍

计算机体系结构期末复习流程大纲

1.存储器和cache 存储器的容量、速度与价格之间的要求是相互矛盾的&#xff0c;速度越快&#xff0c;没bit位价格越高&#xff0c;容量越大&#xff0c;速度越慢&#xff0c;目前主存一般有DRAM构成。 处理器CPU访问存储器的指标&#xff1a; 延迟时间&#xff08;Latency&am…

LeetCode刷题--- 下降路径最小和

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 ​​​​​​http://t.csdnimg.cn/6AbpV 数据结构与算法 ​​​http://t.csdnimg.cn/hKh2l 前言&#xff1a;这个专栏主要讲述动…

Oracle文件自动“减肥”记

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

欧拉图及其应用

什么是欧拉图 提到欧拉图就要谈到哥尼斯堡七桥问题&#xff0c;最初有这样的一个问题的&#xff1a;18世纪中叶&#xff0c;东普鲁士哥尼斯堡城有一条贯穿全城的普雷格尔河&#xff0c;河中有两个岛&#xff0c;通过七座桥彼此相连&#xff0c;如下图所示 问题是这样的&…