【Java 数据结构】集合类 (精华篇)

news2024/11/27 12:35:58

🎉🎉🎉点进来你就是我的人了
博主主页:🙈🙈🙈戳一戳,欢迎大佬指点!

人生格言:当你的才华撑不起你的野心的时候,你就应该静下心来学习!

欢迎志同道合的朋友一起加油喔🦾🦾🦾
目标梦想:进大厂,立志成为一个牛掰的Java程序猿,虽然现在还是一个🐒嘿嘿
谢谢你这么帅气美丽还给我点赞!比个心


目录

前言

一.集合的引入

二. 集合的使用

1. Collection接口中的方法

2.Collection的主要实现类特点

3. Iterator 迭代器的使用

4. Iterator 迭代器的原理

5. List(接口)

6. Set(接口)

7.Queue(接口)

8、Map

三. List集合中:ArrayList 、LinkedList、Vector区别

四. Set集合中:HashSet、TreeSet

TreeSet

HashSet

五. Map:HashMap、TreeMap

HashMap底层原理

JDK7中: 

JDK8中:  与JDK7三点不一样

TreeMap底层原理

六. 集合的线程安全

线程安全的集合

将线程不安全的集合转换为安全的

七. Collections工具类

八. Arrays工具类



前言

本章主要是让大家先了解一下集合类的由来和用法,并简单的介绍一下各个集合类的区别,后续我会对每个集合类的底层源码做一个详细的解释!


一.集合的引入

【1】数组,集合都是对多个数据进行存储操作的,简称为容器。
PS:这里的存储指的是内存层面的存储,而不是持久化存储(.txt,.avi,.jpg,数据库)。

【2】数组:特点:
(1)数组一旦指定了长度,那么长度就被确定了,不可以更改。
int[] arr = new int[6];
(2)数组一旦声明了类型以后,数组中只能存放这个类型的数据。数组中只能存放同一种类型的数据。
int[] arr,String[] s,double[] d.....

【3】数组:缺点:
(1)数组一旦指定了长度,那么长度就被确定了,不可以更改。
(2)删除,增加元素  效率低。
(3)数组中实际元素的数量是没有办法获取的,没有提供对应的方法或者属性来获取
(4)数组存储:有序,可重复 ,对于无序的,不可重复的数组不能满足要求。

【4】正因为上面的缺点,引入了一个新的存储数据的结构---》集合

【5】集合一章我们会学习很多集合,为什么要学习这么多集合呢?
因为不同集合底层数据结构不一样。集合不一样,特点也不一样


Collection体系继承树:

                   蓝色框:接口         红色框:实现类        红色框+阴影:常用实现类

Queue:先进先出的队列。

stack:先进后出的栈

Map体系继承树:

                      蓝色框:接口         红色框:实现类        红色框+阴影:常用实现类 

 Map:具有映射关系(k,v)的 集合,其所有key无序且不可重复。

二. 集合的使用

1. Collection接口中的方法

Collection 接口是层次结构中的根接口。构成 Collection 的单位称为元素。Collection 接口通常不能直接使用,但该接口提供了添加元素、删除元素、管理数据的方法。由于 List 接口与 Set 接口都继承了 Collection 接口,因此这些方法对 List 集合与 Set 集合是通用的。

2.Collection的主要实现类特点

3. Iterator 迭代器的使用

三种方式遍历集合: 普通for循环、增强for循环、Iterator迭代器(重点讲解)

在java.util 包中提供了一个 Iterator 接口,该接口是一个专门对 Collection 进行迭代的迭代器。

lterator迭代器的常用方法

方法

功能描述
hasNext()如果仍有元素可以迭代,则返回 true
next()返回迭代的下一个元素
remove()从迭代器指向的Collection中移除迭代器返回的最后一个元素(可选操作) 

注意:

Iterator的next()方法返回的是Object。

4. Iterator 迭代器的原理

5. List(接口)

List 接口继承了 Collection 接口,定义一个允许重复项的有序集合;按照对象进入顺序进行保存对象,List集合就像是一个数组,有序,长度可变

特点: 有序集合、有重复

操作 :add()、get()、set()、size()、remove()等

常用的实体类: ArrayList等

包括的实体类: ArrayList、Vector、Stack等

具体描述见下图:

6. Set(接口)

Set 接口继承了 Collection 接口,集合元素无序且无重复。

无重复原理:每个Set实现类依赖添加的对象的 equals() 方法来检查独一性,即任意两个元素e1和e2,都有e1.equals(e2)=false

特点: 无序集合、不可重复

操作 :add()、get()、set()、size()、remove()等

常用的实体类: HashSet、TreeSet等

包括的实体类: HashSet、TreeSet、EnumSet、LinkedHashSet等:

具体描述见下图:

7.Queue(接口)

特点: 队列(先进先出、有序表)

主要实现类有: PriorityQueue、ArrayDeque等

8、Map

Map接口含有两个部分(两列):关键字和值 (key-value,简称键值对);key不可重复,value可重复;添加数据时,如果key重复,则用新值替换原有的值。

操作: put(key,value)、remove()、clear()、size()、containsKey(Object key)、containsValue(Object value)

  常用实现类: HashMap、TreeMap

具体描述见下图:

三. List集合中:ArrayList 、LinkedList、Vector区别

ArrayList:底层使用Object数组实现;当数组容量不够时,创建一个新数组,这个新数组的容量是原数组的1.5倍,然后将原数组中的元素复制到这个新数组中。建议使用时,直接在构造方法中指定数组大小。避免扩容,影响效率。

  1. JDK7:当使用无参构造创建列表时,底层默认创建长度是10的Object数组。
  2. JDK8:当是用无参构造创建列表时,底层并不会指定数组的容量,第一次添加容量时才默认创建长度为10的数组

LinkedList底层使用双向链表实现;内部声明了Node类型的next、prev属性,prev指向前一个元素,next指向下一个元素------体现了双向链表,链表更占内存(多了两个引用)。

Vector:线程安全的,里面的方法基本都加了synchornized,因此效率很慢;底层使用Object数组存储;当使用无参构造创建时,JDK7和JDK8都默认创建一个长度为10的数组;当容量不够时会按照原始用量的100%比例扩容。

  1. 对于随机访问ArrayList根据下表查找,时间复杂度为O(1),而LinkedList时间复杂为O(n)。
  2. 对于插入和删除,LinkedList要优于ArrayList;ArrayList需要重新计算位置,移动大量元素,甚至扩容。

四. Set集合中:HashSet、TreeSet

TreeSet

TreeSet有序且不可重复,是基于TreeMap实现的;向TreeSet中添加的对象,一定要是同一类的对象(原理在TreeMap中说)。

HashSet

HashSet是基于HashMap实现的,默认构造函数是构建一个初始容量为16,负载因子为0.75的HashMap。它封装了一个HashMap对象来存储所有的集合元素,所有放入HashSet集合元素实际上是由HashMap的key来保存的,而HashMap的value则存储一个PRESENT,它是一个静态的Object对象。原理在HashMap中说。

不同点:

  1. HashSet中元素可以为null,但只有一个null;TreeSet中不能有null;
  2. HashSet底层使用hash表进行排列,无序;
  3. TreeSet底层用红黑树进行排列;

五. Map:HashMap、TreeMap

HashMap底层原理

JDK7中: 

  1. HashMap 在实例化后创建一个长度为16的Entry数组;HashMap中有一个加载因子默认值为0.75,当存储的元素超过当前数组容量的0.75时会进行扩容,这个加载因子,我们可以通过有参构造创建对象时自己设定。
  2. 在存储数据时,会先计算存储元素的key的hash值来判断其所存储的位置,当两个存储元素的hash值相等时,会调用equals方法判断两个对象是否相等。如果对象相等会进行value值的覆盖;若果对象不相等会在同一个位置以链表形式存储元素。补充说明:
    1. 我们会先调用hashCode方法进行提前校验,避免过多的调用equals方法,以提高效率。这也是为什么我们重写equals方法时要重写hashCode方法。
    2. 同一链表上key的hashCode值不一定相等,且大多数都不相等;因为他的存储方式让我们误以为相等:例如,当前HashMap的容量为16,有两个元素key的Hash值分别为1和17;这时1会被存入数组下标为1的位置,而17此时的存储位置由他的值对存储容量取模的值决定的,取模的值也是1,他们都存在1号位置。但他们hash值根本不一样。
  3. 扩容问题:当容量达到临界时,进行扩容后会重新获得元素的hash值,对hash值”一样“的采用头插法将元素添加到链表。-----会出现扩容循环链表(多线程中出现)。

JDK8中:  与JDK7三点不一样

  1. HashMap 在实例化并添加元素时才创建一个长度为16的Node数组;
  2. JDK8中底层是基于数组+链表+红黑树实现的,底层维护的是Node数组;当数组长度>64且链式数据大于8时,会开启红黑树。(当链表长度过长时会影响我们的查找效率,红黑树可以提高查询效率;之所以不用B/B+树,当数据量不是很多时,数据会挤在一个节点中,这个时候遍历效率相当于退化成了链表)
  3. 扩容时采用尾插法,每次都取最后一个元素放在新的数组链表中,避免了扩容时循环链表的产生。扩容时将元素hash值与旧数组大小做与运算,新增的位为0放在原位置,为1进行移位(原位置+旧数组大小)。

        例如:原数组大小为16,存储元素中有Hash值为1和17 的两个元素。

TreeMap底层原理

基于红黑树实现。映射根据其键的自然排序进行排序。因为底层调用了其键的compare()方法,所以才能进行排序,但同时也规定了存入的key必须是同一类型对象。也可以调用其构造方法,在构造方法中提供 Comparator的实现类自定义排序策略。


六. 集合的线程安全

线程安全的集合

vector、stack、HashTable、ConcurrentHashMap

将线程不安全的集合转换为安全的

  1. 集合类工具:Collections提供了synchornizedXxx()方法,将这些集合类包装成线程安全的集合类。所有的方法都带有同步锁(方法上都加了Synchornized)
  2. JUC:JUC包下提供了大量支持搞笑并发访问的集合类,既能包装良好的性能,又能包装线程安全。(原理在多线程里面讲)
    1. 以Concurrent开头的集合类:写操作线程安全;读取不锁定。
    2. CopyOnWrite开头的集合类:没用锁。采用复制底层数组的方式进行写操作;读的时候读取集合本身;每个线程写的时候复制原数组到当前线程的一个新数组中,然后当前线程对这个副本进行操作。(每个线程拿一个副本数据写操作,写完刷到原数组中)很浪费内存。

七. Collections工具类

Collections是针对集合的工具类,提供了排序、反转、求最值、二分查找等功能, 大大提高了开发人员工作效率。

Collections常用方法说明
sort(List< T> list)根据自然顺序(升序)对指定list集合排序
sort(List< T> list,Comparator< ? super T> c)list-集合;c比较器:按指定比较器c为list排序
max(Collection< ? extends T> collection)根据自然顺序(升序)排序,返回collection的最大元素
min(Collection< ? extends T> collection)根据自然顺序(升序)排序,返回collection的最小元素
binarySearch(List<>list,T key)list-集合,key-指定对象:对List二分查找key(必须先自然升序排序)
reverse(List list)反转List元素的顺序

八. Arrays工具类

Arrays是针对数组的工具类,提供了排序,查找,二分查找等功能。

Arrays常用方法说明
sort(array)对指定的基本数据类型数组array按升序排列
equals(array1,array2)如果两个指定的基本数据类型数组相等返回true
binarySearch(array,val)对基本数据类型数组array进行二分查找val
toString(array)把基本数据类型数组array内容转换为字符串

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

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

相关文章

一本通 3.4.3 图的连通性

1383&#xff1a;刻录光盘(cdrom) 【题目描述】 在FJOI2010夏令营快要结束的时候&#xff0c;很多营员提出来要把整个夏令营期间的资料刻录成一张光盘给大家&#xff0c;以便大家回去后继续学习。组委会觉得这个主意不错&#xff01;可是组委会一时没有足够的空光盘&#xff…

数学术语——指数的发展历程

指数的发展历程 指数(exponents)的历史可以追溯到许多世纪以前&#xff0c;欧几里德(Euclid)被认为是第一个已知的指数用法。他用“幂(power)”这个词来表示我们今天所知的一个数自乘的次数(注&#xff1a;底数连同其右上角的指数一起的整体形式称为“幂”)。古希腊数学家使用…

寄存器:计算机中的小而强大的存储器件

目录 什么是寄存器&#xff1f; 寄存器的作用 提高计算机的性能 存储处理器需要快速访问的数据 存储函数调用时的参数和返回值 存储中间计算结果 寄存器的种类 程序计数器 指令寄存器 状态寄存器 通用寄存器 寄存器的进化过程 寄存器&#xff1a;计算机中的小而强大…

Linux操作基础(文件系统和日志分析)

文章目录一、inode与block1.1inode和block概述1.2 inode包含文件的元信息1.3 linux文件系统的三个时间戳1.4 inode的号码1.5 inode的大小1.6 inode号的特点1.7软连接与硬链接二 、文件恢复2.1 xfsdump恢复2.2 opic恢复方式三 、日志文件3.1 日志文件的分类3.2 日志的格式3.3 常…

大数据分析案例-基于决策树算法构建信用卡违约预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

定制你的专属大模型 Finetuner+体验开启!

如 ChatGPT、GPT4 这样的大型语言模型就像是你为公司请的一个牛人顾问&#xff0c;他在 OpenAI、Google 等大公司被预训练了不少的行业内专业知识&#xff0c;所以加入你的公司后&#xff0c;你只需要输入 Prompt 给他&#xff0c; 介绍一些业务上的背景知识&#xff0c;他就能…

Flink学习:Flink如何打印窗口的开始时间和结束时间

Window一、简介二、代码实现三、测试一、简介 大家知道,Flink用水位线和窗口机制配合来处理乱序事件,保证窗口计算数据的正确性,当水位线超过窗口结束时间的时候,就会触发窗口计算 水位线是动态生成的,根据进入窗口的最大事件时间-允许延迟时间 那么窗口的开始时间和结束时间…

力扣70爬楼梯:思路分析+优化思路+代码实现+补充思考

文章目录第一部分&#xff1a;题目描述第二部分&#xff1a;思路分析2.1 初步分析2.2 问题描述2.3 优化思路第三部分&#xff1a;代码实现第四部分&#xff1a;补充思考第一部分&#xff1a;题目描述 &#x1f3e0; 链接&#xff1a;70. 爬楼梯 - 力扣&#xff08;LeetCode&am…

“衰老标志物”重磅综述:细胞衰老、器官衰老、衰老时钟及其应用

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 随着人口老龄化程度不断加深&#xff0c;实现“健康老龄化&#xff08;healthy aging&#xff09;”已成为我国乃至世界迫切需要解决的重大社会和科学问题。据测算&#xff0c;我国60岁及…

LVGL界面开发之模拟器环境搭建

前言 通常我们在使用 LVGL 进行界面开发时&#xff0c;会先在PC上搭建模拟器环境&#xff0c;而不是直接烧录到硬件板子上&#xff0c;使用模拟器是百利而无一害的&#xff0c;而且它是跨平台的&#xff0c;任何Windows&#xff0c;Linux或macOS系统都可以运行PC模拟器。每当界…

网上投票系统的设计与实现(论文+源码)_kaic

摘要 随着全球Internet的迅猛发展和计算机应用的普及&#xff0c;特别是近几年无线网络的广阔覆盖以及无线终端设备的爆炸式增长&#xff0c;使得人们能够随时随地的访问网络&#xff0c;以获取最新信息、参与网络活动、和他人在线互动。为了能及时地了解民情民意&#xff0c;把…

【高项】项目风险管理与采购管理(十大管理)

【高项】项目风险管理与采购管理&#xff08;十大管理&#xff09; 文章目录1、风险管理1.1 什么是风险管理&#xff1f;1.2 规划风险管理 & 识别风险&#xff08;规划&#xff09;1.3 实施定性风险分析&#xff08;规划&#xff09;1.4 实施定量风险分析&#xff08;规划&…

分布式缓存之Redis(持久化、主从、哨兵、分片集群)

更多内容请参考官网&#xff1a;https://redis.io/Redis持久化Redis有两种持久化方案&#xff1a;RDB持久化和AOF持久化。RDB持久化RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c;也被叫做Redis数据快照。简单来说就是把内存中的所有…

HTML5 表单属性

文章目录HTML5 表单属性HTML5 新的表单属性\<form> / \<input> autocomplete 属性\<form> novalidate 属性\<input> autofocus 属性\<input> form 属性\<input> formaction 属性\<input> formenctype 属性\<input> formmethod…

批量给TXT文档插入带标题合成图片-Chatgpt生成TXT文档配图神器

1、我们用《Chatgpt 3.5-turbo软件》批量生成txt文档&#xff0c;但是这样txt文档里不带图片&#xff0c;直接发布到网站上&#xff0c;光有文字没有图片&#xff0c;效果也不是很理想&#xff0c;就需要一款配图软件。 2、提高文章的可读性和吸引力&#xff1a;插入图片可以丰…

Mybatis(四):自定义映射resultMap

自定义映射resultMap前言一、处理字段和属性的映射关系问题&#xff1a;方案一&#xff1a;使用别名方案二&#xff1a;在mybatis-config.xml中设置mapUnderscoreToCamelCase方案三&#xff1a;在映射文件中设置redultMap二、多对一映射处理问题&#xff1a;方案一&#xff1a;…

Windows10系统安装Redis教程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、下载Redis二、安装或解压三、基本配置设置四、启动四、Redis详细配置前言 由于工作中的项目需要用到Redis&#xff0c;那么记录一下Windows11系统安装Redis…

微服务学习-SpringCloud -Nacos (服务注册源码学习)

文章目录源码版本及下载服务注册核心流程图&#xff08;看不清请双击打开大图&#xff09;源码详解客户端注册源码服务端注册源码源码版本及下载 此次源码版本为1.4.1&#xff0c;2.x版本在服务请求时使用了grpc的方式&#xff0c;所以先以1.4.1版本学习&#xff0c;后续再看2…

uni-app--》如何实现网上购物小程序(中上)?

&#x1f3cd;️作者简介&#xff1a;大家好&#xff0c;我是亦世凡华、渴望知识储备自己的一名在校大学生 &#x1f6f5;个人主页&#xff1a;亦世凡华、 &#x1f6fa;系列专栏&#xff1a;uni-app &#x1f6b2;座右铭&#xff1a;人生亦可燃烧&#xff0c;亦可腐败&#xf…

Jenkins终极部署详细版

&#xff08;一&#xff09;首先你需要配置好虚拟机的JDK环境和Maven环境 1、配置JDK环境 &#xff08;1&#xff09;上传安装包&#xff0c;然后解压 &#xff08;2&#xff09;修改Linux环境变量 具体参考&#xff1a; https://blog.csdn.net/u010227042/article/details/1…