java基础篇(2)——集合框架总结篇

集合框架总结

我们常用的集合框架有Map集合(HashMap、HashTable、TreeMap)、List集合(ArrayList、LinkedList)、Set集合(HashSet)

常用的并发集合框架有ConcurrentHashMap、CopyOnWriteArrayList、CopyOnWriteLinkedList等

一一解析:

Map集合存放key-value结构数据,常用的有HashMap、HashTable、TreeMap

HashMap

数据结构:数组+链表+红黑树

hashmap底层是一个Entry[]数组,数组中存放的是一个Node链表;当put(key,value),一对key,value到hashMap中时,先求key的hash值,找到对应的buket,若该key已存在则替换原来的值,若发生hash碰撞,则将对应的value存到链表中,当链表长度达到8且数组长度达到64时链表转化为红黑树,否则容器扩容。

何时扩容,如何扩容:

HashMap的负载因子是0.75,既数组中的值占全部数组容量的75%时就会扩容,或者容器小于64但其中有链表的长度达到8时也会扩容。扩容为原来容器的两倍。

hashmap的扩容会对链表上的元素重新进行hash计算,标记元素应该是高位还是低位,低位元素依次放在原位置的buket上,高位元素依次放在放在原位置+扩容量的buket上。

特性问题

当增加元素时,链表查长度达到8时转换为红黑树当删除元素时,元素红黑树上元素的数量减少到6是重新转换为链表。链表的查询时间复杂度是O(n),红黑树的时间复杂度是O(lgn)。绘时间复杂度的图便很容易看到,长度为6时,数组效率高于红黑树,长度为8时红黑树效率高于数组。在考虑到转换耗时,所以定在这两个数字做转换。

size的计算:

hashmap中有一个属性值size记录元素个数。新增元素时++size

HashTable既是在HashMap的部分方法上加上synchronized关键是,使其转变为线程安全的HashMap。

TreeMap的底层数据结构是红黑树,所以存入其中的集合遍历时是有序的。

List集合常用的有ArrayList、LinkedList

ArrayList集合底层是一个数组,所以查询效率高,增删效率低,

当数组满的时候扩容,每次扩展为原来的1.5倍。{

newCapacity = oldCapacity + (oldCapacity >> 1);

}。ArrayList中有一个属性值size记录元素个数。插入时先判断是否有足够的空间保存元素,不够就扩容。可以承载的最大元素个数为Integer.MAX_VALUE - 8

LinkedList底层是一个双向链表结构,所以其增删效率高查询效率低。

Set集合常用的有HashSet、TreeSet

HashSet集合底层其实使用HashMap实现的,它利用HashMap的key不能重复的特性,用key存储数据,并将所有的value都是设为null

常用的并发集合框架解析

ConcurrentHashMap是java1.5新增的并发集合框架,它采用了分段锁的设计,初始化时,生成16个segment,每个segment内都有一个类似hashmap的hashEntry。只有在同一个分段内的数据才存在竞态关系,不同的分段锁之间没有锁竞争。所以理论上,ConcurrentHashMap最多可以允许16个线程并发put数据到不同的segment中。

    当put一个key-value到ConcurrentHashMap中时,先对key进行hash计算找到其对应的segment,再将key-value存入对应的hashentry中。

    相比于对整个Map加锁的设计,分段锁大大的提高了高并发环境下的处理能力。但同时,由于不是对整个Map加锁,导致一些需要扫描整个Map的方法(如size(), containsValue())需要使用特殊的实现,另外一些方法(如clear())甚至放弃了对一致性的要求(ConcurrentHashMap是弱一致性的。)

    当统计ConcurrentHashMap包含多少个值时,先后对ConcurrentHashMap统计两次,若两次统计的结果一致,既两次统计的过程中mod值没有改变则返回统计结果;如果两次统计的值不一致,则锁定整个ConcurrentHashMap,for循环统计其size。

CopyOnWriteArrayList和CopyOnWriteLinkedList

    它们分别是基于Copy-On-Write容器的ArrayList和LinkedList。CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

    它适用于读多写少的情况。具体详情参考:Java中的Copy-On-Write容器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值