Java基础--->集合详解

news/2025/1/8 18:16:25/

文章目录

  • 集合
    • Collection
      • List
      • Set
    • Map
      • HashMap
      • Hashtable
      • LinkedHashMap
      • TreeMap

集合

Collection

​ Collection一般存储的是列表数据

List

​ List存储的数据是有序可重复的

ArrayList

​ ArrayList数组存储,可以动态扩容,适合大量查找,线程不安全

// 使用ArrayList进行插入和删除操作时,因为采用数组存储,所以如果执行插入操作时,会默认将元素插入到数组的末尾,这时候时间复杂度为O(1),如果插入到中间位置,时间复杂度就为O(n-1),因为要插入到中间,需要将当前位置和后续的元素向后移一位。
// 支持高效的元素随机访问,可以通过元素的序号快速获取元素对象
// 内存空间浪费主要体现在list列表的结尾会预留一定的容量空间

ArrayList扩容机制

JDK8之前直接创建长度为10的数组elementData,EMPTY_ELEMENTDATA=10是默认值;

JDK8之后只有当add时才初始容量值

ArrayList底层有三种构造器

​ 当创建ArrayList数组时,没有定义初始值,这时候系统给ArrayList赋初始值为10

​ 定义初始值,会进行判断,如果大于0,直接使用定义的初始值,如果等于0,系统赋值默认初始值10,如果小于0,报错

​ 当定义了一个集合对象时,这时候构造器会先将集合转为数组,然后判断数组长度,如果为0,则赋初始值10,如果不为0,判断集合类型是否和ArrayList相同,如果相同直接将该集合赋值给ArrayList,如果不相同,将该集合的长度和元素赋值给ArrayList

ArrayList扩容

​ 当进行新增操作时,判断数组是否需要扩容,就是判断数组需要的容量和当前的容量进行判断,如果大于当前容量,则需要扩容进入grow()方法,首先将数组扩容1.5倍,然后判断数组所需的容量是否小于新扩容的容量,如果大于新扩容的容量,则将新容量赋为数组所需的容量。然后进行判断新长度是否大于最大容量(MAX_ARRAY_SIZE)(Integer.MAX_VALUE-8),如果大于最大容量,则新容量为Integer.MAX_VALUE

LinkedList

​ LinkedList链表存储(双向链表,jdk7之前循环,之后取消了循环链表),适合增、删、改,线程不安全

// 使用LinkedList进行插入和删除操作时,因为采用链表存储,所以头插尾插都不受元素位置影响,时间复杂度为O(1),如果要在指定位置插入元素的话,时间复杂度为O(n),因为需要先将元素移动到指定位置再进行插入。
// 不支持高效的元素随机访问
// 内存空间的花费主要体现在创建存放每一个节点的元素的空间都比ArrayList消耗的空间更多

我们再项目中一般都不会去使用LinkedList,需要用到LinkedList的场景都可以用ArrayList来代替。

Vector

​ Vector数组存储,是List的古老实现类,线程安全

Set

​ Set存储的数据是无序的,也就是存储数据的底层数组并非按照数组索引的位置进行添加,而是根据数据的哈希值决定的;不可重复的,就是说添加元素时,需要同时重写equals()hashCode()方法

comparable 接口实际上是出自java.lang包 它有一个 compareTo(Object obj)方法用来排序

comparator接口实际上是出自 java.util 包它有一个compare(Object obj1, Object obj2)方法用来排序

HashSet

​ 底层数据结构是哈希表,基于HashMap实现的,底层采用HashMap来保存元素

TreeSet

​ 底层是红黑树(自我平衡排序的二叉树),元素是有序的,排序的方式有自然排序和定制排序

LinkedHashSet

​ 底层数据结构是链表+哈希表,内部也是基于HashMap实现的,但是有一点不一样,有链表将Set变得有序,元素插入和取出满足FIFO

Queue// 按特定的排队规则来确定先后顺序,存储的元素是有序的、可重复的。`PriorityQueue`: `Object[]` 数组来实现二叉堆`ArrayQueue`: `Object[]` 数组 + 双指针

Map

​ 底层是键值对存储,key是无序不可重复的,value是无序可以重复的,

HashMap

​ JDK8之前是由数组+链表组成,数组是主体,链表主要是解决哈希冲突而存在的(”拉链法“解决冲突)

​ JDK8之后在解决哈希冲突有了较大的变化,当链表长度大于阈值(默认8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间,Hashtable没有这样的机制

// HashMap是非线程安全的,但是效率高
// 可以存储null的key和value,但是null作为键只能有一个
// 默认初始值大小为16,之后每次扩容容量都会变为原来的两倍
// 如果给定了初始值大小,HashMap会将其扩容为2的的幂次方大小(HashMap 中的tableSizeFor()方法保证)

HashMap底层创建原理

JDK8之前底层是数组+链表,HashMap通过key的hashcode经过扰动函数处理过后得到hash值,然后通过(n-1)&hash判断当前元素存放的位置(n指数组长度),如果当前位置存在元素,则判断该元素与要存入的元素 hash值以及key是否相同,如果相同的话直接覆盖,如果不相同就通过“拉链法”解决冲突。

JDK 8 的 hash 方法 相比于 JDK 7 hash 方法更加简化,但是原理不变。

拉链法:将数组和链表结合,创建一个链表数组,数组中每一个就是一个链表,若遇到哈希冲突,则将冲突的值加到链表中即可,JDK8之后在解决哈希冲突有了较大的变化,当链表长度大于阈值(默认8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。

ConcurrentHashMap

Hashtable

​ 数组+链表组成,数组是Hashtable的主体,链表是主要解决哈希冲突存在的

// Hashtable是线程安全的,因为Hashtable内部的方法都经过synchrnized修饰,基本已经不使用了
// 不可以存储null的key和value,否则会抛空指针异常
// 创建时如果不指定初始值,默认初始大小为11,之后每次扩容,容量都会变为原来的2n+1
// 如果给定了初始值大小,Hashtable会直接使用

LinkedHashMap

​ 继承自HashMap,底层仍然是数组和链表或红黑树组成。

TreeMap

红黑树(自平衡的排序二叉树)

相比于HashMap来说 TreeMap 主要多了对集合中的元素根据键排序的能力以及对集合内元素的搜索的能力。


http://www.ppmy.cn/news/51633.html

相关文章

Linearx配置环境

代码地址 gitssh.dev.azure.com:v3/linearx/PowerDDS/PowerDDS LinearX-5G Wifi pwd: 50186058 Windows报错可以搜索错误代码找官方给出的解决方案 最新版本cmake:ubuntu 20.04安装(升级)cmake - 知乎 (zhihu.com) gtest:gtest的安装_liuzubing的博客…

文献阅读 Meta transfer learning-based super-resolution infrared imaging

题目 Meta transfer learning-based super-resolution infrared imaging 基于元迁移学习的超分辨率红外成像 摘要 我们提出了一种具有元迁移学习和轻量级网络的红外图像超分辨率方法。我们设计了一个轻量级网络来学习低分辨率和高分辨率红外图像之间的映射。我们使用外部数据…

python-数据库-4

数据查询 分页(限制查询返回条数) limit 子句 create table test(id int primary key auto_increment,name char(5),gerden varchar(2),grade double(4 , 1) );insert into test(name , gerden , grade) values (刘水东,男,89), (曹洪清,男,95), (轻岚,男,88), (泽瑞,男,90…

【SCI征稿】IEEE旗下1区人工智能类SCI, 稳定检索22年,仅3个月左右录用~

一、期刊简介: 1区人工智能类SCI&EI (高质量) 【期刊概况】IF:6.0-7.0, JCR1区, 中科院3区; 【终审周期】走期刊部系统,3个月左右录用; 【检索情况】SCI&EI双检,正刊; 【数据库收录年份】2001…

JVM中的垃圾回收概念及其基础算法说明

文章目录 一、 垃圾回收概述1、什么是垃圾?2、为什么我们需要GC 二、垃圾回收之判别对象死活1、标记阶段:引用计数算法2、标记阶段:可达性分析算法 二、 finalization 机制三、整理和清除对象1、标记-清除算法(Mark-Sweep&#xf…

应急照明系统在民用建筑的设计应用与产品选型

【摘要】应急照明分为备用照明、安全照明及疏散照明。文章介绍了应急照明系统的设计、灯具选择、灯具布置、配电等要求。并结合实例进行疏散照明的计算,以指导应急照明系统的设计与应用。 【关键词】照度;光通量;消防应急灯具;A型…

C#开发的OpenRA的游戏侧边界面

C#开发的OpenRA的游戏侧边界面 OpenRA游戏开始之后,会在右边提供一个游戏侧边界面, 通过这个游戏界面,可以查看游戏状态、执行一些特殊的命令,以及雷达显示, 还有创建各种需要的建筑物,以及生产各种兵种,飞机等等。 这个游戏界面,就是给玩家提供一个操作平台,因此它…

Redis序列化设置以及jetcache连接Redis序列化的设置

1、问题 问题:我在使用jetchche进行连接redis的时候,存入redis的value一直使用的是redis默认的序列化方式,是使用的jdk序列化。当我使用jetcache向redis存入一个对象 存入redis的结果: 这是使用jdk序列化的结果。 但是我记得使用redis的时候…