容器类

java容器有两类框架,一类是collection,一类是map

collection接口

Map接口

 

 

 

 

object中的类

散列表 树对应的容器类

hashmap解决冲突的方法

1.再哈希 2.链表法

底层实现原理

数组+链表

哈希表

数组+链表+红黑树

技术本质

数据存储(数据结构+算法)

数组:查找时间复杂度o(1)  删除或者插入o(n)

jdk1.7   头插法

1.return h&(length-1) 作为存放的位置,length为数组的长度(2的n次方),h为hashcode,

 (h=key.hashcode();)

(h先会进行右移操作,因为length-1后只有h的后四位才能影响结果,将h右移后,使得H的高位也能影响到最终结果,增加散列性。)

(实质就是把length-1后,所得二进制后四位全是1,所以最终得到的结果完全取决于hashcode的后四位,这样得到存储Index不会重复。)

2.扩容

扩容条件:map阈值&&数组中的每个位置不为孔

扩容后,进行元素转移,链表顺序会变成倒序

3.新值每次放在数组中,而旧值在新值的链表上

4.为什么线程不安全

1、put的时候导致的多线程数据不一致。
这个问题比较好想象,比如有两个线程A和B,首先A希望插入一个key-value对到HashMap中,首先计算记录所要落到的桶的索引坐标,然后获取到该桶里面的链表头结点,此时线程A的时间片用完了,而此时线程B被调度得以执行,和线程A一样执行,只不过线程B成功将记录插到了桶里面,假设线程A插入的记录计算出来的桶索引和线程B要插入的记录计算出来的桶索引是一样的,那么当线程B成功插入之后,线程A再次被调度运行时,它依然持有过期的链表头但是它对此一无所知,以至于它认为它应该这样做,如此一来就覆盖了线程B插入的记录,这样线程B插入的记录就凭空消失了,造成了数据不一致的行为。

2、另外一个比较明显的线程不安全的问题是HashMap的get操作可能因为resize而引起死循环(cpu100%)。在元素转移时,因为链表的逆序,导致死循环。

加锁:hashtable

ConcurrentHashmap

 

segment []

先确定放在哪个segment,再确定具体位置

例如:16,8(并发级别)

segment[8]

jdk1.8 数组+单向链表+红黑树 尾插法

在多个节点在hash出现碰撞时,存储在1个链表中,那么要查找某一个节点,就会花费o(n)时间

数组默认大小为16,最大值2的30次7方,

扩容:负载因子=0.75,数组容量=16*0.75

阈值:链表长度过长时,将链表变成红黑树,减少查询深度

阈值2:小于这个值,再变成链表

concurrentHashMap的实现 采用的什么锁

 

 

linkedhashmap treemap

arraylist:底层是数组

linkedlist:底层是双向链表

copyonwirtearraylist

 

转载于:https://www.cnblogs.com/NeverGiveUp0/p/11138430.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值