关于HashMap--个人学习记录

说说 Java 中 HashMap 的原理?

HashMap底层在1.7是数组+链表 在1.8后是数组+链表+红黑树

具体而言对于 put(key,value)操作来说 我们会计算出key的哈希值 然后通过数组长度-1 && key 计算出该存储的下标位置如果 如果说发现该下标有了数据了 那么代表此时发生了哈希冲突 对于put操作来说会将其依次匹配该下标位置的链表元素 如果说equals(key)相同就将value覆盖 如果遍历完了链表还没有相同的key 就插入到链表尾节点

对于扩容机制来说 如果说数组的大小达到了负载因子 也就是0.75 那么此时就会将数组大小翻倍里面的元素进行重新计算放到新数组当中 称为rehash

Java 中 ConcurrentHashMap 1.7 和 1.8 之间有哪些区别?

1.7的时候核心思想是采取分段锁 每个 Segment 内部维护一个 HashEntry<K,V>[] table 数组,相当于一个小的 HashMap segment继承ReentranLock 不同线程访问不同的段 互相之间不影响 每次都会锁住整个segment桶数组 + 其下的所有链表

对于1.8来说 锁的颗粒度更精细了 锁细化到每个槽位 每次插入的时候如果下标位置没有节点先通过CAS插入新的节点 如果有节点通过synchronized将这个节点上锁 执行后续操作 别的线程就无法访问这个节点以及后面的链表 或 红黑树了 每次锁住的都是头节点synchronized(头节点)

为什么 JDK 1.8 对 HashMap 进行了红黑树的改动?

因为HashMap 1.7以及之前 如果说冲突过多链表过长 就会从o(1) 退化到 o(n) 所以1.8在链表长度大于8并且数组长度大于64的时候转换为红黑树 如果说数组长度较低的话本身hash冲突就比较激烈所以规定了必须要数组长度大于64才可以

JDK 1.8 对 HashMap 除了红黑树还进行了哪些改动?

1.7使用的是头插法 1.8后使用尾插法 因为头插法会有循环链表的问题

对于扩容机制来说也是同理 JDK 1.7 :扩容后,每个元素必须调用函数重新计算在新数组中的下标位置。

对于1.8来话说利用了2的幂次方的特性 扩容后小标只有两种可能 意识原位置 二是 一道道原位置加旧数组长度 低位保持不变 高位集体搬家

Java 中有哪些集合类?请简单介绍

List 有序可重复 按照下标访问 ArrayList底层是数组 增删较慢但是查询较快 LinkedList底层是链表增删较快但是查询较慢 不过也是增删较快也是针对于头节点和尾节点来说

Set set是不允许有重复元素 HashSet基于哈希表 key用来存储元素 value存储固定值 LinkedHashSet用链表维护顺序 TreeSet基于红黑树 元素按大小排序

Map HashMap基于哈希表键 LinkedHashMap 底层基于哈希表和双向链表 维护了插入顺序和存储顺序一致 HashMap在并发编程下线程有问题ConcurrentHashMap则是更好的选择

相关推荐
卓怡学长2 小时前
w1基于springboot高校学生评教系统
java·spring boot·tomcat·maven·intellij-idea
lvyuanj2 小时前
Java AI开发实战:Spring AI完全指南
java·人工智能·spring
lifallen2 小时前
如何保证 Kafka 的消息顺序性?
java·大数据·分布式·kafka
Geoking.2 小时前
后端Long型数据传到前端js后精度丢失的问题(前后端传输踩坑指南)
java·前端·javascript·后端
Seven972 小时前
【从0到1构建一个ClaudeAgent】规划与协调-子Agent
java
宠友信息2 小时前
社交软件源码哪个渠道好
java·微服务·架构·社交电子·springboot·uniapp
improvement...2 小时前
Maven 编译打包全指南:整体 / 逐个打包 + 核心参数详解
java·maven
_李小白2 小时前
【OSG学习笔记】Day 41: ReadFileCallback 与 WriteFileCallback(自定义文件读取)
java·笔记·学习
每天吃饭的羊2 小时前
nest,java对比
java·开发语言