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

java集合总结

1.常见集合

  • Collection
    • List:有序可重复集合,可直接根据元素的索引来访问
      • Vector-Stack
      • ArrayList
      • LinkedList
    • Queue:队列集合
      • Deque-LinkedList、ArrayDeque
      • PriorityQueue
    • Set:无序不可重复集合,只能根据元素本身来访问
      • Hashset-LinkedHashSet
      • SortedSet-TreeSet
      • EnumSet
  • Map:存储key-value对的集合,可根据元素的key来访问value
    • IdentityHashmap
    • WeakHashMap
    • HashMap-LinkedHashMap
    • HashTable-Properties
    • SortedMap-TreeMap
    • EnumMap

2.线程安全和线程不安全

  • 线程安全:Hashtable、ConcurrentHashMap、Vector(synchronized)、Stack
  • 线程不安全:HashMap、ArrayList、LinkedList、HashSet、TreeSet、TreeMap

3.ArrayList与LinkedList

  • 线程安全:不安全
  • 底层数据结构
    • ArrayList:Object数组
    • LinkedList:双向循环链表
  • 插入删除是否受位置影响
    • ArrayList:数组存储,插入和删除元素的时间复杂度受元素位置影响,
    • LinkedList:链表存储,插入和删除元素时间复杂度不受位置影响
  • 是否支持快速随机访问
    • ArrayList:实现了RandomAccess接口,能随机访问
    • LinkedList:不支持高效的随机元素访问
  • 内存空间占用
    • ArrayList:在list列表的结尾会预留一定的容量空间
    • LinkedList:每个元素都需要消耗比ArrayList更多的空间(要存放直接后继和直接前驱和数据)

4.ArrayList扩容机制

本质:计算出新的扩容数组size后实例化,并将原有数组内容复制到新数组去,默认情况下,新的容量会是原容量的1.5倍

5.Array和ArrayList

  • Array可以包含基本类型和对象类型,ArrayList只能包含对象类型
  • Array大小是固定的,ArrayList的大小是动态变化的
  • ArrayList提供了更多的方法和特性,eg:addAll(),removeAll(),iterator()等

6.HashMap

  • 底层数据结构
    • 1.7 数组+链表,链表主要解决哈希冲突
    • 1.8 数组+链表+红黑树,链表过长会严重影响HashMap的性能,红黑树搜索时间复杂度是O(logn),链表是O(n)。链表和红黑树的转换
      • 当链表超过8且数据总量超过64才会转红黑树
      • 将链表转换成红黑树前会判断,如果当前数组的长度小于64,会选择先进行数组扩容,而不是转换为红黑树,以减少搜索时间。
  • 解决hash冲突
    • 开放定址法(再散列法):以p为基础,再hash,以此类推,直到不冲突
    • 再哈希法:提供多个hash函数,直到不冲突
    • 链地址法:HashMap采用的方法。哈希值相同的元素构成一个单链表
    • 建立公共溢出区:将哈希表分为公共表和溢出表,当溢出发生时,将所有溢出数据统一放到溢出区
  • 加载因子
    • Node[] table初始化长度为16,负载因子默认0.75,threshold是Hashmap所能容纳键值对的最大值,threshold=length*Load factor。在数组定义好长度之后,负载因子越大,所能容纳的键值对个数越多。
    • 0.75是对空间和时间效率的一个平衡选择,一般不要修改,除非在时间和空间比较特殊的情况下
      • 如果内存空间很多而又对时间效率要求很高,可以降低负载因子Load factor的值
      • 如果内存空间紧张而对时间效率要求不高,可以增加负载因子loadFactory的值,这个值可以大于1
  • key的存储索引怎么计算的
    • 根据key的值计算出hashcode的值
    • 根据hashcode计算出hash的值
    • hash&(length-1)计算得到存储位置
  • put流程
    • 根据key计算出hash值,找到该元素再数组中存储的下标
    • 如果数组是空的,调用resize进行初始化
    • 如果没有哈希冲突直接放在对应的数组下标里
    • 如果冲突,且key已经存在,覆盖掉value
    • 如果冲突,发现该节点是红黑树,就将这个节点挂在树上
    • 如果冲突后是链表,判断该链表是否大于8
      • 如果大于8并且数组容量小于64,就扩容。
      • 如果节点大于8并且数组容量大于64,结构转为红黑树,
      • 否则,链表插入键值对,若key存在,就覆盖掉value
  • 扩容
    • 容量超过负载因子所定义的容量之后,就会扩容。将HashMap的大小扩大为原来数组的两倍,并将原来的对象放到新的数组中。
    • 1.8两处优化
      • resize之后,元素的位置在原来的位置或者原来位置+oldCap。如果bit是0,索引没变,如果是1则为原索引+oldcap
      • 1.7中rehash的时候,旧链表迁移新链表的时候,如果在新表的数组索引位置相同,则链表元素会倒置(头插法),1.8不会倒置,使用尾插法。
  • hashMap的key:一般用Integer,String这种不可变类当key,String最常用
    • 因为字符串是不可变的,所以创建的时候hashcode就被缓存了,不需要重新计算
    • 获取对象的时候要用到equals和hashcode,键对象正确的重写这两个方法是非常重要的。
  • 为什么是线程不安全的
    • 多线程下扩容死循环(1.7头插法导致的,1.8不会出现环形链表的问题)
    • 多线程的put可能导致元素的丢失。如果计算出的索引位置相同,会造成前一个key被后一个key覆盖,从而导致元素丢失。
    • put 和 get 并发时,可能导致get为null。线程1执行put,因为元素个数超出threshold导致rehash,线程2此时执行get,有可能导致这个问题。

7.ConcurrentHashMap

  • 实现原理
    • 1.7
      • 由segment数组结构和HashEntry数组结构组成,把哈希桶切分成小数组,每个小数组有n个HashEntry组成。
        • segment继承了ReentrantLock,所以segment是一种可重入锁,扮演锁的角色,HashEntry用于存储键值对数据
    • 1.8
      • 选择了与hashmap相同的数组+链表+红黑树结构。在锁的实现上,抛弃了原有的Segment分段锁,采用cas+synchronized实现更加低粒度的锁。将锁级别控制在了更细粒度的哈希桶元素级别,提高并发度
  • put逻辑
    • 1.7
      • 尝试获取锁,获取失败,利用自旋获取锁,如果自旋重试次数超过64次,则改为阻塞获取锁
      • 获取到锁后
        • 将当前segment中的table通过key的hashcode定位到HashEntry
        • 遍历该HashEntry,如果不为空则判断传入的key和当前遍历的key是否相等,相等则覆盖旧的value
        • 不为空则需要新建一个HashEntry并加入到Segment中,同时会先判断是否需要扩容
        • 释放segment的锁
    • 1.8
      • 根据key计算出hash的值
      • 判断是否需要进行初始化
      • 定位到Node,拿到首节点f,判断首节点f
        • 如果为null,则通过cas的方式尝试添加
        • 如果为f.hash=MOVED=-1,说明其他线程在扩容,参与一起扩容
        • 如果都不满足,synchronized锁住f节点,判断是链表还是红黑树,遍历插入
      • 当在链表长度达到8的时候数组扩容或者将链表转换为红黑树
  • get方法不需要加锁
    • Node的元素val和指针next是用volatile修饰的,在多线程环境下线程A修改节点的val或者新增节点的时候是对线程B可见的。
    • 与volatile修饰的哈希桶没有关系:哈希桶主要是保证在数组扩容的时候保证可见性
  • 不支持key或者value为null
    • value不为null:无法判断是映射的value为null,还是没找到对应的key而为null。
  • 并发度
    • 1.7 默认16,可以在构造函数中设置,如果设置了并发度,ConcurrentHashMap会使用大于等于该值的最小的2的幂指数作为实际并发度,即如果设置的是17,则实际并发度为32
  • 迭代器是强一致性还是弱一致性
    • HashMap是强一致性,ConcurrentHashMap是弱一致性
    • 迭代器创建后会按照哈希表结构遍历每个元素,在遍历过程中,内部元素可能发生变化,如果变化发生在已遍历过的部分,迭代器就不会反映出来,而如果变化发生在未遍历过的部分,迭代器会 发现并反映出来,即弱一致性。

8.Hashtable

  • 使用Synchronized来实现线程安全,多线程访问的时候,只有一个线程能访问或操作对象。

9.多线程下安全的操作map还有其他方法么

  • Collections.synchronizedMap:对方法进行加同步锁。如果传入的是HashMap对象,也是对HashMap做了一层包装,里面使用对象锁来保证多线程场景下线程安全,本质也是全表锁。

10.Collection框架中实现比较

  • 内部比较器:实体类实现Comparable接口,并实现compareTo(T t)方法
  • 外部比较器:实现Comparator接口的compare(T t1,T t2)

11.Iterator 和 ListIterator

  • Iterator:遍历,可以遍历所有集合,eg:Map,List,Set,但只能再向前方向上遍历集合中的元素
  • ListIterator:只能遍历List实现的对象,但可以向前和向后遍历集合中的元素
    • 区别:
      • 添加元素:Iterator无法向集合中添加元素,ListIterator可以向集合中添加元素
      • 修改元素:Iterator无法修改元素,ListIterator可以使用set()修改集合中的元素
      • 索引:Iterator无法获取集合中元素的索引,ListIterator可以获取结合中的索引

12.快速失败和安全失败

  • 快速失败fail-fast
    • 在用迭代器遍历一个集合对象时, 如果遍历过程中集合对象的内容进行了修改(增删改),则会抛出ConcurrentModificationException
    • 原理:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个modCount变量,集合在被遍历期间如果内容发生变化,就会改变modCount的值,每当迭代器使用hashNext/next遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历,否则抛出异常,终止遍历。
    • 注:这里异常的抛出条件是检测到modCount != expectedmodCount这个条件,如果集合发生变化时修改modCount值刚好又设置为了expectedmodCount值,则异常不会抛出,因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的bug
    • 场景:java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改),比如hashmap,arrayList这些集合类
  • 安全失败fail-safe
    • 采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历
    • 原理:由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发ConcurrentModification Exception
    • 缺点:基于拷贝内容的优点避免了ConcurrentModificationException,但同样滴,迭代器并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的
    • 场景:java.util.concurrent包下的容器都是安全失败的,可以在多线程下并发使用,并发修改,比如ConcurrentHashMap

相关文章:

java集合总结

1.常见集合 Collection List:有序可重复集合,可直接根据元素的索引来访问 Vector-StackArrayListLinkedList Queue:队列集合 Deque-LinkedList、ArrayDequePriorityQueue Set:无序不可重复集合,只能根据元素本身来访问…...

list交并补差集合

list交并补差集合 工具类依赖 <dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.8.1</version> </dependency><dependency><groupId>commons-collections&…...

【微信小程序】父组件修改子组件数据或调用子组件方法

一、使用场景 页面中用到了自定义组件形成父子组件关系&#xff0c;在父组件某个特定时期想要操作子组件中的数据或方法&#xff0c;比如离开页面的时候清空子组件的数据。 二、方法 父组件可以通过this.selectComponent方法获取子组件实例对象&#xff0c;这样就可以直接访…...

frp通过nginx映射multipart/x-mixed-replace; boundary=frame流媒体出外网访问

要通过Nginx访问multipart/x-mixed-replace流媒体协议&#xff0c;并通过FRP进行映射访问&#xff0c;你可以按照以下步骤进行操作&#xff1a; 配置Nginx以支持multipart/x-mixed-replace流媒体协议。你需要编辑Nginx的配置文件&#xff08;通常是nginx.conf&#xff09;&…...

Kubernetes概述

Kubernetes概述 使用kubeadm快速部署一个k8s集群 Kubernetes高可用集群二进制部署&#xff08;一&#xff09;主机准备和负载均衡器安装 Kubernetes高可用集群二进制部署&#xff08;二&#xff09;ETCD集群部署 Kubernetes高可用集群二进制部署&#xff08;三&#xff09;部署…...

Jmeter教程

目录 安装与配置 一&#xff1a;下载jdk——配置jdk环境变量 二&#xff1a;下载JMeter——配置环境变量 安装与配置 一&#xff1a;下载jdk——配置jdk环境变量 1.新建环境变量变量名:JAVA_HOME变量值&#xff1a;&#xff08;即JDK的安装路径&#xff09; 2.编辑Path%J…...

用Rust实现23种设计模式之建造者模式

当使用 Rust 实现建造者模式时&#xff0c;我们可以通过结构体和方法链来实现。建造者模式是一种创建型设计模式&#xff0c;它允许你按照特定的顺序构建复杂对象&#xff0c;同时使你能够灵活地构建不同的变体。下面是一个使用 Rust 实现建造者模式的示例&#xff0c; 在示例中…...

聚观早报 | 腾讯字节等企业驰援防汛救灾;新能源车7月销量单出炉

【聚观365】8月4日消息 腾讯字节等企业驰援防汛救灾新能源车7月销量成绩单出炉Model Y等车型低温续航衰减严重华为Mate60系列猜想图曝光支付宝做短视频引来羊毛党 腾讯字节等企业驰援防汛救灾 近日&#xff0c;京津冀地区遭遇极端降雨天气&#xff0c;引发洪涝和地质灾害&…...

Crack:CAD Exchanger SDK 3.20 Web Toolkit 应用

在CAD Exchanger SDK 版本 3.20.0中&#xff0c;我们在 Web Toolkit 中包含了绘图、BIM 和 MCAD 查看器的示例&#xff0c;以展示如何使用每个工具可视化数据。这些查看器具有显示不同类型数据的特定功能&#xff0c;允许用户根据自己的需求单独使用它们。我们将继续增强每个查…...

改造 ChatGPT-Next-Web 项目重新生成 Docker 镜像

改造 ChatGPT-Next-Web 项目重新生成 Docker 镜像 0.背景1. 修改代码2. 生成 Docker 镜像3. 上传 Docker 镜像4. 运行 Docker 镜像 0.背景 需要通过 ChatGPT-Next-Web 使用自己搭建的 OpenAI API 兼容的服务器&#xff0c;需要对 ChatGPT-Next-Web 项目的少量代码进行改造。 …...

git修改commit日志

由于公司对版本提交日志进行检查&#xff0c;如果不符合要求&#xff0c;则push失败。 以下是修改commit日志的方法&#xff1a; 1.进入到提交代码文件所在目录&#xff0c;即git所在目录下 cd app-repository 2.git log git log commit bf29e3e5e799d364fe2975677baf18c9…...

Qt之qml和widget混合编程调用

首先是创建一个widget项目 然后需要添加qml和quick的插件使用 QT quickwidgets qml 接着要在界面上创建一个quickwidget和按钮 创建一个c对象类 QObjectQml #ifndef QOBJECTQML_H #define QOBJECTQML_H#include <QObject> #include <QDebug> class QObjectQml …...

深度学习torch基础知识

torch. detach()拼接函数torch.stack()torch.nn.DataParallel()np.clip()torch.linspace()PyTorch中tensor.repeat()pytorch索引查找 index_select detach() detach是截断反向传播的梯度流 将某个node变成不需要梯度的Varibale。因此当反向传播经过这个node时&#xff0c;梯度…...

【JAVA】正则表达式是啥?

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️初识JAVA】 文章目录 前言正则表达式正则表达式语法正则表达式的特点捕获组实例 前言 如果我们想要判断给定的字符串是否符合正则表达式的过滤逻辑&#xff08;称作“匹配”&#xff09;&#xff0c…...

网络安全之原型链污染

目录&#xff1a; 目录&#xff1a; 一、概念 二、举例 三、 实操了解 总结 四、抛出原题&#xff0c;历年原题复现 第一题&#xff1a; 五、分析与原理 第二题&#xff1a; 八、分析与原理 九、具体操作&#xff0c;payload与结果 结果&#xff1a; 一、概念 Java…...

【腾讯云Cloud Studio实战训练营】使用Cloud Studio迅捷开发一个3D家具个性化定制应用

目录 前言&#xff1a; 一、腾讯云 Cloud Studio介绍&#xff1a; 1、接近本地 IDE 的开发体验 2、多环境可选&#xff0c;或连接到云主机 3、随时分享预览效果 4、兼容 VSCode 插件 5、 AI代码助手 二、腾讯云Cloud Studio项目实践&#xff08;3D家具个性化定制应用&…...

【计算机网络】第四章 网络层(一)

文章目录 第四章 网络层4.1 网络层概述4.2 网络层提供的两种服务4.2.1 小结 第四章 网络层 网络层是计算机网络体系结构中的一个关键层&#xff0c;位于传输层上方、数据链路层下方。它负责将传输层提供的数据分割成适当大小的数据包&#xff0c;并在不同网络之间进行路由选择和…...

Elasticsearch删除文档

根据id删除 例如删除id为110的文档 DELETE /ffbf/_doc/110返回信息 {"_index" : "ffbf","_type" : "_doc","_id" : "110","_version"...

MySQL数据库如何实现AX规范

本文我们来讨论 MySQL 的 XA 规范有哪些应用相关的内容。 MySQL 为我们提供了分布式事务解决方案&#xff0c;在前面的内容中 聊一聊分布式事务的解决方案 提到过 binlog 的同步&#xff0c;其实是 MySQL XA 规范的一个应用&#xff0c;那么 XA 规范是如何定义的&#xff0c;具…...

mac安装nvm

如果安装过node&#xff0c;须得卸载 sudo npm uninstall npm -gsudo rm -rf /usr/local/lib/node /usr/local/lib/node_modules /var/db/receipts/org.nodejs.*sudo rm -rf /usr/local/include/node /Users/$USER/.npmsudo rm /usr/local/bin/nodesudo rm /usr/local/share/m…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...