当前位置: 首页 > news >正文

Java集合 总结篇(全)

Java集合

img

集合底层框架总结

List

代表的有序,可重复的集合。

  • ArrayList -- 数组 -- 把他想象成C++中的Vector就可以,当数组空间不够的时候,会自动扩容。 -- 线程不安全

  • LinkedList -- 双向链表 -- 可以将他理解成一个链表,不支持随机存取,但是增加删除特别方便。

  • Vector -- 数组 -- 线程安全

comparable Comparator 的区别

comparable 是Java中的一个接口,定义在lang包下,他的比较方法是comparableTo。他是一个Java 中内置的比较方法,不是独立的。例如我可以根据年龄,来为对象排序。这个comparableTo 是写在类之中的。

class Person implements Comparable<Person> {private String name;private int age;
​public Person(String name, int age) {this.name = name;this.age = age;}
​// Implementing compareTo method of Comparable interface@Overridepublic int compareTo(Person otherPerson) {return Integer.compare(this.age, otherPerson.age);}
}
​
public class Main {public static void main(String[] args) {List<Person> people = new ArrayList<>();people.add(new Person("Alice", 30));people.add(new Person("Bob", 25));people.add(new Person("Charlie", 35));
​Collections.sort(people);
​for (Person person : people) {System.out.println(person);}}
}

Comparator 是一个独立的接口,定义在Util 包下。他如果对对象进行排序,需要重写 compare 方法,然后在外部对具体如何排序进行书写,也正因为写在外部,所以可以有多种排序方式,与之相反的Compareable 接口由于在类内部,所以只有一种排序方式,不可改变。

class Person implements Comparable<Person> {private String name;private int age;
​public Person(String name, int age) {this.name = name;this.age = age;}
​// Implementing compareTo method of Comparable interface@Overridepublic int compareTo(Person otherPerson) {return Integer.compare(this.age, otherPerson.age);}
​// Getter methods for name and agepublic String getName() {return name;}
​public int getAge() {return age;}
​// toString method for printing Person objects@Overridepublic String toString() {return name + " - " + age;}
}
​
public class Main {public static void main(String[] args) {List<Person> people = new ArrayList<>();people.add(new Person("Alice", 30));people.add(new Person("Bob", 25));people.add(new Person("Charlie", 35));
​Collections.sort(people);
​for (Person person : people) {System.out.println(person);}}
}

ArrayList如何序列化

transient 修饰 存储元素的elementData,目的是不让被修饰的成员属性序列化。

那为什么不可以直接序列化 ArrayList?

因为ArrayList的空间可能是100,但是只有60个有元素,那么就极大的浪费空间,且效率低下。

如何序列化

通过的是readObject和writeObject方法,实际使用的是流的方式。

ObjectOutputStreamObjectInputStream来进行序列化和反序列化。

ArrayList的扩容机制

首先,我们在创建ArrayList时,我们可以指定ArrayList的初始容量,但随着add()方法,不断往ArrayList添加元素,这个时候ArrayList的容量满了,我们需要对 ArrayList 进行扩容。

流程为:创建了一个当前数组容量*1.5大小的 ArrayList,然后将原来的数组中的元素利用Arrays.copyOf() 方法放入 新数组中。再将准备新加入的元素加入新数组中。

图示:

堆栈过程图示:
add(element)
└── if (size == elementData.length) // 判断是否需要扩容├── grow(minCapacity) // 扩容│   └── newCapacity = oldCapacity + (oldCapacity >> 1) // 计算新的数组容量│   └── Arrays.copyOf(elementData, newCapacity) // 创建新的数组├── elementData[size++] = element; // 添加新元素└── return true; // 添加成功
​
LinkedList 为什么不能实现RandomAccess接口

RandomAccess 是一个标记接口,用来表明实现该接口的类支持随机访问(即可以通过索引快速访问元素)。由于 LinkedList 底层数据结构是链表,内存地址不连续,只能通过指针来定位,不支持随机快速访问,所以不能实现 RandomAccess 接口。

Queue

  • PriorityQueue -- 数组来实现二叉堆

  • ArrayQueue -- 数组 + 双指针

Set

代表的有序,不可重复的集合。

  • HashSet(无序,唯一) -- 基于 HashMap 实现,底层是哈希表

  • LinkedHashSet(HashSet的子类,有序) -- 基于LinkedHashMap实现,底层是链表 + 哈希表

  • TreeSet (有序,唯一)-- 红黑树

Map

以键值对方式存储。代表的是键值对的集合。

  • HashMap -- JDK1.8 前:数组+链表。JDK1.8后:如果链表阈值大于默认值(8),会将链表转换为红黑树,但转换前会先判断数组大小是否小于64,如果小于的话,优先数组扩容。总结:数组+链表或红黑树。

  • LinkHashMap -- 数组+链表或红黑树。不同的是,在HashMap基础上,增加了一条双向链表,可以保证顺序与插入顺序一致。

  • TreeMap -- 红黑树。 因为TreeMap还实现了 SortedMap 和 NavigableMap 接口,所以会比 HashMap 多了搜寻和排序的功能。可以自定义排序规则。

HashMap详解

数据结构:

HashMap -- JDK1.8 前:数组+链表。JDK1.8后:如果链表阈值大于默认值(8),会将链表转换为红黑树,但转换前会先判断数组大小是否小于64,如果小于的话,优先数组扩容。总结:数组+链表或红黑树。使用了拉链法来解决的哈希冲突。

JDK1.8 前:

JDK1.8后:

线程安全:

非线程安全,但是HashTable是线程安全的。因为HashTable中的方法基本上都经过 synchronized 修饰过的。

初始容量和扩容机制:

HashMap如果未指定初始大小,那么默认初始容量大小是16,且每次扩容都是之前的二倍。如果给定初始容量大小 n,那么容量为给定大小的2 的n次幂。

而HashTable 如果未指定初始大小,那么默认初始容量大小是11,且每次扩容都是之前的 2n + 1 。如果指定初始容量大小,那么容量直接就是给定的大小。

为什么 HashMap 的⻓度为什么是 2 的幂次方

因为 Hash 值范围非常大,但是空间是不能容得下这么多哈希值的,所以需要 Hash值 数组长度进行取模运算。也就是 Hash % length ,但是这个这个值是与 Hash & (length - 1 )是相等的。

举个例子如果 数组长度是 16,hash值是 10101 ,hash & (ength - 1) = 10101 & 1111。这样可以看到 hash 值的后四位就可以被用来计算数组的索引。

  1. 会方便计算,也可以使其分布更加均匀。(因为与 hash 值有关)。

  2. 并且如果数组长度是2 的幂次方,就可以用 与运算。也会使效率更高。

如果初始化一个HashMap长度为17,还是会变成 32 容量。

HashMap 的 put 流程

三分恶面渣逆袭:HashMap插入数据流程图

先利用 hashcode 获取哈希值,然后根据哈希值和数组长度算出键值对在数组中的索引。如果当前数组的桶为空,直接添加。如果不为空,判断key 相同与否,如果相同,则覆盖,不相同的话遍历链表或者遍历树。在链表中,如果 key 相同,则覆盖,如果key 不存在,添加进链表中,作为尾节点,并判断如果超过链表阈值,则转换为红黑树。

HashMap的查询,删除的时间复杂度

HashMap可以直接根据哈希码来确认数组下标,所以查询和删除的时间复杂度都是 o(1) 。但是如果发生哈希冲突的话,链表还未转换成红黑树,时间复杂度就变成了o(n),n是链表长度,如果转变成了红黑树,时间复杂度变成了 o(logn).

ConcurrentHashMap

从上文已知,HashMap 是线程不安全的,那如果我们想用线程安全的哈希表,就可以用 ConcurrentHashMap。

在Jdk 1.8 之前,ConcurrentHashMap 的底层数据结构是 分段数组 + 链表的形式。每个分段可以独立锁定,当需要读取数据的时候,不需要锁震整个数组,只需要锁定当前数据所在的段的段就可以。可以提高并发的性能。当一个线程锁上一个数据段的时候,其他的数据段仍然可以被另外的线程读取。 如果有些方法需要跨段,那么就可以按顺序锁住所有的段,然后再按顺序释放就可以。

Segment 数组中的每个元素包含⼀个 HashEntry 数组,每个 HashEntry 数组属于链表结构。

这样就可以保证线程安全。

JDK1.8之后,ConcurrentHashMap 取消了 Segment 分段数组,只保留了一大个数组,也就是 table 数组。取而代之,保证线程安全用的是CAS 和 synchronized 锁,避免不必要的锁的开销。另一个变化是像HashMap一样增加了红黑树,防止链表长度过长。

JDK 1.8 最大并发数是Node数组的大小,而Jdk1.7并发数是 Segment 的数量。

ConcurrentHashMap 和 HashTable 的区别

首先,他们俩都是线程安全的,但是数据结构不同。

HashTable 的数据结构利用了 数组加链表,ConcurrentHashMap 的数据结构参考上文。

其次,实现线程安全的方式也不同,HashTable使⽤ synchronized 来保证线程安全,同一时段,只能一个线程访问,效率低下。

相关文章:

Java集合 总结篇(全)

Java集合 集合底层框架总结 List 代表的有序&#xff0c;可重复的集合。 ArrayList -- 数组 -- 把他想象成C中的Vector就可以&#xff0c;当数组空间不够的时候&#xff0c;会自动扩容。 -- 线程不安全 LinkedList -- 双向链表 -- 可以将他理解成一个链表&#xff0c;不支持…...

Dubbo分层架构深度解析

引言 Dubbo作为一款备受欢迎的高性能、轻量级的Java RPC框架&#xff0c;在现代分布式系统中扮演着至关重要的角色。随着互联网行业的快速发展&#xff0c;服务间的通信变得越来越频繁&#xff0c;这也使得对于高效、可靠的远程通信方案的需求变得愈发迫切。在这样的背景下&am…...

LocalDate 数据库不兼容问题,因为LocalDate 是 long 类型的

我今天遇到一报错&#xff1a; SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession316f9272] was not registered for synchronization because synchronization is not active JDBC Connection [HikariProxyConnection2127597288 wrapping com.mysql.cj.jdbc…...

RVM(相关向量机)、CNN_RVM(卷积神经网络结合相关向量机)、RVM-Adaboost(相关向量机结合Adaboost)

当我们谈到RVM&#xff08;Relevance Vector Machine&#xff0c;相关向量机&#xff09;、CNN_RVM&#xff08;卷积神经网络结合相关向量机&#xff09;以及RVM-Adaboost&#xff08;相关向量机结合AdaBoost算法&#xff09;时&#xff0c;每种模型都有其独特的原理和结构。以…...

Java--方法的使用

1.1什么是方法 方法顾名思义就是解决问题的办法&#xff0c;在程序员写代码的时候&#xff0c;会遇到很多逻辑结构一样&#xff0c;解决相同问题时&#xff0c;每次都写一样的代码&#xff0c;这会使代码看起来比较绒余&#xff0c;代码量也比较多&#xff0c;为了解决这个问题…...

linux - 主次设备号自动申请

alloc_chrdev_region 原型如下&#xff0c;该函数向内核申请一个空闲的主设备号。 alloc_chrdev_region(&g_aputriger_dev, 0, APUTRIGER_MAX_NUM, "aputriger0"); 第四个参数是我们使用cat /proc/devices 看到的名称 /*** alloc_chrdev_region() - register a…...

我写了一套几乎无敌的参数校验组件!基于 SpEL 的参数校验组件「SpEL Validator」

前言 大家好&#xff0c;我是阿杆&#xff0c;不是阿轩。 参数校验这个东西&#xff0c;很多情况下都是比较简单的&#xff0c;用 NotNull、Size 等注解就可以解决绝大多数场景&#xff0c;但也有一些场景是这些基本注解解决不了的&#xff0c;只能用一些其他的方式处理&…...

输入序列太长 gan CGAN

transformer序列长度大导致计算复杂度高 GAN 2. 训练过程 第一阶段&#xff1a;固定「判别器D」&#xff0c;训练「生成器G」。使用一个性能不错的判别器&#xff0c;G不断生成“假数据”&#xff0c;然后给这个D去判断。开始时候&#xff0c;G还很弱&#xff0c;所以很容易被…...

uni-app scroll-view隐藏滚动条的小细节 兼容主流浏览器

开端 想写个横向滚动的列表适配浏览器&#xff0c;主要就是隐藏一下滚动条在手机上美观一点。 但是使用uni-app官方文档建议的::-webkit-scrollbar在目标标签时发现没生效。 .scroll-view_H::-webkit-scrollbar{display: none; }解决 F12看了一下&#xff0c;原来编译到浏览…...

Java常用API之LinkedList类解读

写在开头&#xff1a;本文用于作者学习我将官方文档中LinkedList 1.6版本中类中绝大部分API全测了一遍并打印了结果&#xff0c;日拱一卒&#xff0c;常看常新。 自己补充了一些对该数据结构的理解&#xff0c;如有不对的地方&#xff0c;请各位指正&#xff0c;谢谢。 首先&…...

移动端自适应

基本实现核心思想 基本原则上是&#xff0c;布局更多地使用flex&#xff0c;然后尺寸使用rem&#xff0c;vw&#xff0c;vh为单位如果是根据不同的屏幕需要有不同的布局了&#xff0c;一般通过检测屏幕尺寸换不同的站点或者媒体查询使用css rem 以html字体太小为1rem的大小&…...

自动化运维工具-Ansible

一、Ansible概述 Ansible是一种基于python开发的自动化运维工具&#xff0c;它只需要在服务端安装ansible&#xff0c;无需在每个客户端安装客户端程序&#xff0c;通过ssh的方式来进行客户端服务器的管理&#xff0c;基于模块来实现批量数据配置、批量设备部署以及批量命令执…...

力扣:62. 不同路径

62. 不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&…...

store内路由跳转router.push

选择action还是mutation 选择action mutation 是用来改变state的&#xff0c;不应该包含路由相关操作mutation是同步执行的&#xff0c;不应该包含异步操作&#xff0c;而路由是异步操作 action中进行路由跳转 因为vuex中没有this&#xff0c;所以不能用this.$router&#…...

ChatGPT Web Midjourney一键集成最新版

准备工具 服务器一台 推荐使用浪浪云服务器 稳定 安全 有保障 chatgpt api 推荐好用白嫖的api 项目演示 项目部署 浏览器访问casaos 添加软件原添加 https://gitee.com/langlangy_1/CasaOS-AppStore-LangLangy/raw/master/chatmjd.zip 安装此软件 等待安装 安装后再桌面设置…...

springboot mongodb分片集群事务

前置 mongodb分片集群想要使用事务,需要对应分片没有仲裁节点 代码 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId><version>2.1.0.RELEASE</version></d…...

node报错——解决Error: error:0308010C:digital envelope routines::unsupported——亲测可用

今天在打包vue2项目时&#xff0c;遇到一个报错&#xff1a; 最关键的代码如下&#xff1a; Error: error:0308010C:digital envelope routines::unsupportedat new Hash (node:internal/crypto/hash:80:19)百度后发现是node版本的问题。 在昨天我确实操作了一下node&…...

golang系统内置函数整理

go语言中有很多系统内置的函数&#xff0c; 为了方便学习&#xff0c;对系统内置函数的函数定义 入参和返回值做如下整理&#xff0c;以方便学习和记忆。 Go语言系统级别的内置函数不多&#xff0c;但是包含的知识点可不少&#xff0c;是学习go语言说必须要搞明白的基础知识 …...

武汉星起航:五对一服务体系,助力创业者成功进军跨境电商市场

随着全球化的深入发展和互联网的普及&#xff0c;跨境电商已成为越来越多国内创业者的首选。然而&#xff0c;跨境电商市场的复杂性和多变性使得许多新手创业者望而却步。在这样的背景下&#xff0c;武汉星起航电子商务有限公司以其独特的五对一服务体系&#xff0c;为创业者提…...

C++常用库函数——strcmp、strchr

1、strcmp&#xff1a;比较两个字符串的值是否相等 例如 char a1[6] "AbDeG",*s1 a1;char a2[6] "AbdEg",* s2 a2;s1 2;s2 2;printf("%d \n", strcmp(s1, s2));return(0); s1指向a1&#xff0c;s2指向a2&#xff0c;strcmp表示比较s1和s…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...