Java中各种集合的异同与使用


Collection< E >是所有集合类的祖先 我们从这个类往下延伸

1.List


不同点:

名称数据结构安全性插入和删除(时间复杂度)getIndex内存空间占用
ArrayList数组非同步,不安全首尾O(1),index O(n-i))高效结尾会预留一定的空间
LinkedList双向链表非同步,不安全O(n)较慢每一个元素都耗时
Vector(淘汰)数 组线程安全(synchronized)---------------
  • ArrayList增删没有想象中慢,ArrayList的增删底层调用的copyOf()被优化过,加上现代CPU对内存可以块操作,普通大小的ArrayList增删比LinkedList更快。

2.Set

  • HashSet
  • LinkedHashSet
  • TreeSet

不同点:

名称顺序基础
HashSet无序基于HashMap
LinkedHashSet自动排序基于TreeMap
TreeSet维护“插入顺序”基于HashSet,是HashSet的扩展
  • Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false

3.Map

不同点:

名称实现继承是否允许null值扩容方式存储方式
HashMap实现Map接口继承 AbstractMap 类允许key和value为null值size*2,且size必定为2^n1.如果冲突数量于8,则是以链表方式解决冲突。2.如果当冲突大于等于8时,就会将冲突的Entry转换为红黑树进行存储。3如果当数量小于6时,则又转化为链表存储。
HashTable实现Map接口继承 Dictionary类键值对都不能为空size*2+1链表方式存储
LinkedHashMap实现Map接口继承 HashMap类允许key和value为null值基于拉链式散列结构即由数组和链表或红黑树组成
TreeMap实现NavigableMap接口继承 AbstractMap类不允许Key为null红黑树(自平衡的排序二叉树)

已上是常见集合的梳理,但是在多线程环境下 , Vector被淘汰 , 使用synchronizedList又过于笨重

4. JUC下常用的几个线程安全容器

安全容器详解入口

1. CopyOnWriteArrayList

CopyOnWriteArrayList博客入口

2. CopyOnWriteArraySet

同CopyOnWriteArrayList

3. ConcurrentLinkedQueue

ConcurrentLinkedQueue

4. ConcurrentSkipListMap

ConcurrentSkipListMap

5. ConcurrentHashMap

ConcurrentHashMap博客入口

因为HashTable也是线程安全的,总结一下不同点:

  • 底层数据结构:
    • JDK1.7的 ConcurrentHashMap 底层采用 分段的数组+链表 实现,JDK1.8 采用的数据结构跟HashMap1.8的结构一样,数组+链表/红黑二叉树。
    • Hashtable 和 JDK1.8 之前的 HashMap 的底层数据结构类似都是采用 数组+链表 的形式,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的;
  • 实现线程安全的方式(重要):
    • ① 在JDK1.7的时候,ConcurrentHashMap(分段锁) 对整个桶数组进行了分割分段(Segment),每一把锁只锁容器其中一部分数据,多线程访问容器里不同数据段的数据,就不会存在锁竞争,提高并发访问率。 到了 JDK1.8 的时候已经摒弃了Segment的概念,而是直接用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 synchronized 和 CAS 来操作。(JDK1.6以后 对 synchronized锁做了很多优化) 整个看起来就像是优化过且线程安全的 HashMap,虽然在JDK1.8中还能看到 Segment 的数据结构,但是已经简化了属性,只是为了兼容旧版本;
    • ② Hashtable(同一把锁) :使用 synchronized 来保证线程安全,效率非常低下。当一个线程访问同步方 法时,其他线程也访问同步方法,可能会进入阻塞或轮询状态,如使用 put 添加元素,另一个线程不能使用 put 添加元素,也不能使用 get,竞争会越来越激烈效率越低。

如何选用集合?

主要根据集合的特点来选用,比如我们需要根据键值获取到元素值时就选用Map接口下的集合,
需要排序时选择TreeMap,不需要排序时就选择HashMap,需要保证线程安全就选用ConcurrentHashMap.
当我们只需要存放元素值时,就选择实现Collection接口的集合,
需要保证元素唯一时选择实现Set接口的集合比如TreeSet或HashSet,
不需要就选择实现List接口的比如ArrayList或LinkedList,
然后再根据实现这些接口的集合的特点来选用。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aloneii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值