您的位置:首页 > 职场人生

个人集合汇总(面试使用)

2019-06-11 22:31 211 查看

一.Map

hashMap hashTable concurrentHashMap

1.核心的常量:负载因子默认0.75(从查询性能和hash表所占内存开销两方面参考折中取值), 初 始化容量 16(二进制机制)都是2的幂次方。主要是length-1后的二进制都是111,相比1101,增加空间使用,减少碰撞记录,查询快;

当链表大于8时候转为红黑树

2.核心的方法:getNode putVaule resize

3.扩容机制: 新建数据,将旧数据复制到新数组中

4.hashTable: 安全---方法都加锁了 synchronized 针对代码块,使用在put方法上,性能低

hashmap的key -value都可以为null,hashtable不能

hashtable是同步的,hashmap不是。所有hashmap适合单线程环境,hashtable适合多线程(安全)

5. concurrenthashMap:https://mp.weixin.qq.com/s/h6SMb1y7XVJa8jc-Xu3LYw

1.7版本---使用了分段锁机制,并发时只是对一个桶加锁,其他15个桶可以正常访问。segment

1.8版本---链表+数据+红黑树结构,采用cas(乐观锁机制)+锁住node,用sizectl值不同控制业务。cas就是不可能死锁,要么改变,要么循环继续执行盘点能否更改。

6.hashmap(int a,int b)校验初始化的容量值和加载因子的值

MAXIMUM_CAPACITY 容量最大值,当初始化超过时会取最大值。2*30 2的30次方,1073741824最大容量

HashMap的数据存储实现原理

流程:

1. 根据key计算得到key.hash = (h = k.hashCode()) ^ (h >>> 16);

2. 根据key.hash计算得到桶数组的索引index = key.hash & (table.length - 1),这样就找到该key的存放位置了:

① 如果该位置没有数据,用该数据新生成一个节点保存新数据,返回null;

② 如果该位置有数据是一个红黑树,那么执行相应的插入 / 更新操作;

③ 如果该位置有数据是一个链表,分两种情况一是该链表没有这个节点,另一个是该链表上有这个节点,注意这里判断的依据是key.hash是否一样:

如果该链表没有这个节点,那么采用尾插法新增节点保存新数据,返回null;如果该链表已经有这个节点了,那么找到该节点并更新新数据,返回老数据。

二.List

1.arrayList:初始化10容量,调用grow()方法扩容,每次1.5倍。将旧数据copyof()复制新数组中;查更快,操作少。

2.LinkedList:增删快,因为该的节点索引少。双向循环链表数据结构。不安全。

三.Set

1.HashSet:无序,不可重复。底层是hash实现,没有修改方法。存取快

2.TreeSet: 无序,不可重复。底层二叉树实现,

3.LinkedHashSet:差用hash表存储,双向链表结构。

 

总结:安全的就是带锁,vecoter,hashtable

四。iterater 和listiterator 区别

1.iterator 遍历list和set;只能向前遍历

listiterator:只能遍历list;可以双向遍历;继承了iterator接口,增加一些额外功能,例如增加一个元素,替换一个元素

五。遍历List不同方式;安全性

foreach it.hasNext

使用迭代器更加线程安全,且如果集合元素改变会抛错

六:hashMap 工作原理

HashMap在map.entry静态内部类实现中存储key-value对。在put时,用key,hashcode一些hash算法去查存储的key-value对的索引,如果entry存在就使用equals比较key值。如果存在覆盖vaule值,如果不存在创建一个新的entry。当get时,用hashcode找到数组中的索引,用equals找到entry,然后返回值。

所以:我们可以根据需求定义我们的初始容量。扩容时消耗内存。也是底层复制到新的数组中

七:任何类可以作为map的key:但是注意里面的hashcode和equals方法是否重写

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: