收藏

一些个容器

2022-02-18  本文已影响0人  go_2021

arrayList和linkedList

arrayList是数组,默认10个大小 然后满了之后1.5倍扩容。
linkedList是双向链表。
CopyOnWriteArrayList
改的时候加个r锁,然后new 新的数组->system.arraycopy复制到新的数组里,方法来扩容或者缩短。
stringbuffer,stringbuilder,也是system.arraycopy~但是这里没有创建新数组,而是修改了原数组。
https://www.jianshu.com/p/a0582f2c5ec8

hashMap

hashMap 数组+链表来实现 默认16 扩容 *2。

hashSet
hashMap包一层,添加就是把值当做key加到hashMap里,方法都是调用hashMap的。

为啥是 16
因为 确定key 数组下标的是 (n-1) & hash
的算法 如果太大 浪费初始的空间 16 对应 n-1 的二进制是 1111。

为啥hash 不用hashcode?
因为hashcode是int 对应2进制32。hash的运算是h^(h>>>16),32位右移16和原来的32取异或,等同前16位和后16位取异或。
就是要尽量和每一位数据都有关系,这样减少碰撞。

为啥0.75?
这就设计到 一个阈值的问题了 太小可能导致内存浪费 太大链表太长 影响查询效率。

位运算:
与(&) 非(~) 或(|) 异或( ^ 相同为0 否则为1)

线程安全问题
1.并发put,key丢失。并发到同一槽里。
2.扩容时,getkey为null。

  1. jdk7扩容+头插,形成环。

jdk1.8

hashmap

concurrentHashMap

linkedHashMap

treeHashMap

上一篇 下一篇

猜你喜欢

热点阅读