Java集合底层原理总结

news2024/11/18 16:31:58

文章目录

  • 一、集合分类
  • 二、遍历集合方式
  • 三、单列集合
    • 3.1 List
      • 3.1.1 ArrayList底层分析
      • 3.1.2 LinkedList底层分析
    • 3.2 Set
      • 3.2.1 HashSet(无序)底层分析
      • 3.2.2 LinkedHashSet(有序,存取一致)
      • 3.2.3 TreeSet(可排序)
  • 四、双列集合Map
    • 4.1 HashMap(无序)
    • 4.2 LinkedHashMap(有序)
    • 4.3 TreeMap(可排序)

一、集合分类

  1. 单列集合(List Set Queue)
  2. 双列集合(Map)
    在这里插入图片描述

注意点:Collection是一个接口,Collections是一个工具类,Map不是Collection的子接口。

二、遍历集合方式

创建一个List集合:

        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
  1. 传统for循环下标索引(只适合List)
        for(int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
缺点:只有List能使用;通过get方法获取元素效率较低。
  1. iterator迭代器循环(读取时不能对元素进行添加删除)
		// 获取迭代器
        Iterator<String> iterator = list.iterator();
		// hasNext()判断迭代器当前指向是否存在值,next()得到当前迭代器指向的值并后移一位
        while(iterator.hasNext()) {
            System.out.println(iterator.next());
        }
注意点:使用迭代器时不能对集合进行添加或删除元素。
  1. 增强for循环(对增强for循环内的值进行修改是不会影响集合本身的)
        for(String s: list) {
            s = "12";
            System.out.println(s);
        }
        for(String s: list) {
            System.out.println(s);
        }
注意点:
第一次增强for循环输出的是三次12,第二次增强for循环输出的是1 2 3,显然第一次循环对集合的修改不会影响集合本身的值;
同样,增强for循环是基于iterator实现的,因此在使用时不能添加或删除元素。
  1. lambda表达式
        list.forEach(s -> System.out.println(s));
总结:传统的通过索引取值的方式只适合List且效率较低;
	通过迭代器获取元素效率较高,并且增强for循环简化了获取迭代器的步骤,推荐使用;
	lambda表达式代码最简单,但可读性差,推荐在代码简单时使用。	

三、单列集合

3.1 List

	List特点:有序(存和取顺序一致),可重复,有索引。
	List分为ArrayList和LinkedList。

在这里插入图片描述

3.1.1 ArrayList底层分析

	1.开始创建一个新数组时,数组大小size为0
	2.向数组添加一个元素时,数组大小初始化size为10
	3.当添加一个元素时,超过了数组大小10,数组进行扩容,扩容为原来大小的1.5倍,也就是15
	4.当一次添加多个元素时,超过了数组大小15,数组进行扩容,此时不再扩大为原来的1.5倍,而以新添加的元素大小为准
	例如添加100个元素,此时数组大小为15+100=115

注意点:ArrayList是一个动态数组,初始大小为10。当添加第一个元素时,数组大小才为10,否则为空。当添加单个元素时,超过数组大小则数组扩容为原来的1.5倍,当添加多个元素时,超过数组大小则以添加的元素多少进行扩容。

数组(Array)和ArrayList的区别:
		1.数组可以包含基本数据类型和对象,ArrayList只能包含对象;
		2.数组大小是固定的,ArrayList是动态变化的;
		3.ArrayList提供了更多方法和特性。

3.1.2 LinkedList底层分析

LinkedList底层是一个双向链表。链表结点由前一个地址值,当前元素,下一个地址值三部分组成,还存储了链表中的第一个和最后一个结点地址。
由于LinkedList是一个双向链表,可以实现队列和栈。

3.2 Set

Set特点:无序(输入的顺序和输出的顺序不一定一样),不可重复,无索引。
Set下的实现类如下图所示,Set分别被HashSet、TreeSet实现,HashSet下还有一个LinkedHashSet类。
预备知识:平衡二叉树(任意结点的左右子树高度不超过1)、红黑树(是一个二叉查找树但不是高度平衡,满足特有的红黑规则)

在这里插入图片描述

hashCode方法默认根据地址值计算哈希值,一般需要重写,重写根据对象属性值计算哈希值,那么只要对象属性值相同,计算出来的哈希值就相同。
hashCode计算出来的哈希值可能会出现重复的情况。

3.2.1 HashSet(无序)底层分析

特点:无序,不可重复,无索引。
底层结构:哈希表(JDK8以前:数组+链表,JDK8以后:数组+链表+红黑树)
实现:
	1.创建一个默认长度为16,默认加载因子为0.75的数组。
	2.根据哈希值和数组大小计算存入位置。idx =h & (length - 1)。
	3.判断存入位置是否为空,若为空,直接存入。
	4.若不为空,调用equals比较属性值是否一样。
	5.若一样,则不用存入,若不一样,则形成链表存入。
		JDK8以前:新元素存入数组,老元素挂在新元素下面
		JDK8以后:新元素直接挂在老元素下面
	6.若超过16*0.75=12数组大小,则扩容数组大小两倍为32。
	7.JDK8以后,当链表长度超过8且数组长度大于等于64时,链表转换为红黑树。
	
为什么HashSet是无序的?
	当HashSet取元素时,按数组遍历,再根据数组中的链表遍历,因此存取是无序的。
为什么HashSet无法通过索引取值?
	由于HashSet是由数组+链表+红黑树组成的,因此不方便使用索引读取。
HashSet是如何保证无重复元素的?
	通过HashCode和equals保证HashSet内部元素是不重复的。

HashSet默认创建长度16,加载因子0.75的数组。

3.2.2 LinkedHashSet(有序,存取一致)

特点:有序,不可重复,无索引。
继承HashSet。
实现:
	基于哈希表,额外使用双链表记录结点存储顺序。

3.2.3 TreeSet(可排序)

特点:可排序,不可重复,无索引。默认输出数值从小到大进行排序,字符字符串按ASCII码表中的数字升序进行排序)。
实现:底层是红黑树(不需要重写hashCode和equals),增删改查性能较好。

四、双列集合Map

HashSet、LinkedHashMap、TreeSet底层都是基于Map实现的,也就是Map中的底层结构是和Set类似的,只是Map中是根据Key值判断是否存在某元素。我们只要熟悉了Set,Map的原理和Set都是类似的。
在这里插入图片描述

4.1 HashMap(无序)

原理类似HashSet。
通过键计算哈希值,如果存入位置不为空,判断属性值是否一样,若一样,替换原来的值。

4.2 LinkedHashMap(有序)

同上,基于双链表实现输入和输出一致。

4.3 TreeMap(可排序)

同上,基于红黑树实现输出的升序。

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

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

相关文章

[LitCTF 2023]easy_shark

下载附件解压出现密码提示 使用010editor打开&#xff0c;发现frflags和deflags都被修改了&#xff0c;这就会造成压缩包伪加密 将它们都改回0&#xff0c;另存为再打开&#xff0c;不再出现密码提示 使用wirshark打开 过滤http并追踪&#xff0c;在最后一个包里找到了类似fla…

车载以太网 - SomeIP - 协议用例 - on-wire

目录 Specification of the SOME/IP on-wire format 1.1、验证Response报文中的源IP地址为Request报文中的目标IP地址

搭建stm32电机控制代码框架(二)——Stm32CubeMx配置定时器

搭建了基础的环境&#xff0c;配置了一个简单的工程后&#xff0c;CubeMx的基本操作就会了。然后基于这个操作往下推进&#xff0c;开始对关键模块定时器的攻略&#xff0c;这个部分需要先熟悉一下Stm32的定时器基本原理。 《STM32参考手册》中仅对定时器的介绍就已经占了100多…

C++的最后一道坎 | 百万年薪的程序员

| 导语 C 的起源可以追溯到 40 年前&#xff0c;但它仍然是当今使用最广泛的编程语言之一&#xff0c;C发明人Bjarne Stroustrup 一开始没想到 C 会获得如此大的成功&#xff0c;他说&#xff1a;“C 的成功显然令人惊讶。我认为它的成功取决于其最初的设计目标&#xff0c;就是…

用nginx实现一个直播服务—RTMP推流和HTTP-FLV拉流

目录 一、环境准备 二、安装编译nginx所需的安装包和下载nginx原代码包 三、nginx配置 四、启动nginx服务 五、测试推流和拉流服务 六、摄像头数据采集 七、查看统计 这篇文章主要记录用nginx实现直播服务&#xff0c;通过RTMP推流和通过HTTP-FLV或RTMP拉流&#xff0c;…

DJ5-4 链路层交换机

目录 一、链路层交换机 二、交换机&#xff1a;支持多节点同时传输 三、交换机&#xff1a;转发表或称交换表 四、交互机&#xff1a;自学习 1. 单个交换机自学习/转发的例子 2. 多个交换机自学习/转发的例子 五、交换机&#xff1a;数据帧的过滤/转发 六、交换机的交换…

css基础技巧

1. emmet语法 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style>…

如何在CSDN获取更多的铁粉?

一、铁粉的定义 要想获取铁粉&#xff0c;首先我们得知道什么是铁粉&#xff0c;根据官方给出定义是下面这样的&#xff1a; 【铁粉】具体规则如下&#xff1a; 铁粉 90 天内有阅读&#xff0c;购买专栏或其他互动&#xff0c;并且原力等级 > 0 的粉丝。 也就是说你的原力…

数据结构——二叉树_(上)

学习二叉树之前我们首先要对树有一个认识&#xff0c;树是一种非线性结构&#xff0c;它是由n(n>0)个有限节点组成的一个具有层次关系的节点&#xff1b;而这个层次结构倒过来看就十分的像一棵树&#xff0c;所以起名树结构。 跟现实中的树一样&#xff0c;树结构也有一个根…

Altium Designer18基础

原理图 第5课 元件库介绍及电阻容模型的创建.mp4_哔哩哔哩_bilibili 原理图库&#xff08;schLib&#xff09; 1. 创建原理图库&#xff1a; panels -> SCHLIB&#xff1a;左侧弹出SCH Lib窗口 Add&#xff1a;新建原理图库 点击原理图库名称&#xff1a;进入原理图库设置…

【短视频矩阵系统源码搭建+二开源码定制部署】

短视频矩阵源码的框架有很多种&#xff0c;根据不同的业务需求和技术要求&#xff0c;可选择适合的框架。目前常见的短视频矩阵源码框架有&#xff1a;Flutter、React Native、Vue、Angular等前端框架&#xff1b;Spring Boot、Laravel等后端框架&#xff1b;FFmpeg、Pusher、W…

ChatGPT“保姆级教程”——手把手教你5分钟快速AI智能文字转爆款视频(剪映+百度AIGC平台)

目录 前言ChatGPT 剪映ChatGPT生成视频文档安装专业版剪映使用剪映一键出片保姆集教程 百度AIGC平台注册百度AIGC平台使用百度AIGC平台一键出片保姆集教程 总结其它资料下载 前言 在这个数字时代&#xff0c;视频已经成为了最流行的内容形式之一。而如何自动将文字转化为引人…

JavaScript实现输入学生姓名,按q键程序结束的代码

以下为实现输入输入学生姓名&#xff0c;按q键程序结束的程序代码和运行截图 目录 前言 一、输入学生姓名&#xff0c;按q键程序结束 1.1 运行流程及思想 1.2 代码段 1.3 JavaScript语句代码 1.4 运行截图 前言 1.若有选择&#xff0c;您可以在目录里进行快速查找&#…

Web应用技术(第十三周/第二次练习/7h)

本次练习基于how2java和课本&#xff0c;学习MyBatis高级映和分页 1.MyBatis高级映射&#xff1a;1.1 相关XML标签及其属性&#xff1a;&#xff08;1&#xff09;mapper标签&#xff1a;&#xff08;2&#xff09;DOCTYPE标签&#xff1a;&#xff08;3&#xff09;typeAliase…

【MySQL】MySQL体系架构

文章目录 背景一、MySQL体系架构二、网络连接层三、数据库服务层3.1 连接池3.2 系统管理和控制工具3.3 SQL接口3.4 解析树3.5 查询优化器3.6 缓存 四、存储引擎层五、系统文件层5.1 日志文件5.2 数据文件5.3 配置文件5.4 pid文件5.5 socket文件 背景 很多小伙伴工作很长时间了…

【OJ比赛日历】快周末了,不来一场比赛吗? #05.27-06.02 #14场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 以下信息仅供参考&#xff0c;以比赛官网为准 目录 2023-05-27&#xff08;周六&#xff09; #8场比赛2023-05-28…

Holocube-第一集

准备工作&#xff1a; 装备&#xff1a; ESP 8266 D1 MINI1.3寸 TFT 屏幕分光棱镜25.4mm面包板、杜邦线、数据线等配件 软件&#xff1a; Arduino(本人使用1.8.16)---驱动ch341 初始arduino简单程序&#xff0c;对esp8266上传代码&#xff0c;能正常运行。正式开始 坑1&…

Day0:Windows编程环境搭建

前言&#xff1a;学习一个东西&#xff0c;首先要有三问&#xff1a; 1. 这个东西是什么&#xff1f; 2. 为什么要学它&#xff1f; 3. 该怎么学习它&#xff1f; 第一问是要明白你要学习的东西它是什么&#xff0c;你就会对它有一个整体的了解。这也是第二问的半个答案&#x…

有没有想过一种可能,30岁之后,转行去做IT售前?

灵魂拷问 IT行业的变化是非常迅速的&#xff0c;各种新技术、新产品、新观念、新的业务模式层出不穷&#xff0c;不仅是我们&#xff0c;客户也在不断地学习进步&#xff0c;因此我们注定要终身学习。 IT售前这个岗位为许多IT职场人提供了一种新的选择: 你不需要成为某一方面…

微信小程序推送消息

微信小程序推送消息 前言一、推送消息&#xff1a;小程序“订阅消息”功能二、开发步骤1.小程序调用wx.requestSubscribeMessage&#xff0c;进行消息订阅用户授权2.小程序调用wx.login&#xff0c;获取code3.后端访问请求&#xff0c;获取用户openId4.后端访问请求&#xff0c…