集合(二)

Collection
List:
  • 可以允许重复对象,可以插入多个null元素,是一个有序容器
  • 其常用子类有ArrayList、LinkedList、Vector
ArrayList、LinkedList和Vector的区别
  • ArrayLis和Vector底层都是基于数组实现的,随机访问效率较高,插入效率低
  • ArrayLis线程不安全,不可以设置空间扩容方法。
  • Vector线程安全,可以设置空间扩容方法
  • LinkList底层是基于双端链表,线程不安全,随机访问效率较低,随机插入效率高。
Set:
  • 不允许重复对象
  • 其常用子类有HashSet、LinkedHashSet、TreeSet
Hashset
  • 底层数据结构是哈希表,HashSet不保证元素的顺序但保证元素必须唯一。
LinkedHashSet
  • 底层数据结构是哈希表+链表,哈希表用来保证元素唯一,链表用来保证元素的插入顺序.
TreeSet
  • 底层数据结构是红黑树,TreeSet不仅保证元素的唯一性,也保证元素的顺序。
  • 一般用于存储有序的集合(自然排序和比较器排序)
异同点:
  • 都保证了元素的唯一性,线程都不安全
  • HashSet不保证元素的顺序
  • LinkHashSet保证FIFO即按插入顺序排序
  • TreeSet保证元素的顺序,支持自定义排序规则
  • HashSet,LinkedHashSet允许添加null值,TreeSet不允许添加null值。
Map:
  • Map不是Collection的子接口或实现类。Map是一个接口
  • Map 的每个Entry都特有两个对象,也就是一个键一个值,Map可能会持有相同的值对象但键对象必须是唯一的,Map里可以拥有随意个null值但最多只能有一个null键.
  • 其常用子类有:HashMap,TreeMap,HashTable,LinkedHashMap,ConcurrentHashMap.
hashMap
  • 底层基于哈希表实现的,每个元素都是一个key–value对,对内部通过单链表解决冲突问题,容量不足时会自动增长,实现了Serializable接口,它支持序列化,实现了Cloneable接口,能被克隆。
  • HashMap 默认的初始化大小为16。负载因子是0.75,当容量达到容量的0.75倍时开始扩容,容量变为原来的两倍。
  • 链表长度大于8时,结构由链表转为红黑树
  • HashMap不同步,线程不安全。
HashTable
  • hashtable继承Dictionary类。
  • hashtable中的key value都不允许出现null值
  • 线程安全
  • HashTable扩容后是原来的2倍+1
TreeMap
  • TreeMap是利用红黑树来实现的,实现了SortMap接口,能够对保存的记录根据键进行排序。所以一般需要排序的情况下是选择TreeMap来进行。
  • 继承于AbstractMap,所以它是一个Map,即一个key-value集合。
  • 实现了NavigableMap接口,意味着它支持一系列的导航方法。比如返回有序的key集合。
ConcurrentHashMap
  • 线程安全的HashMap
  • 采用了CAS算法+同步锁,保证线程安全
LinkedHashMap
  • 有序的HashMap
  • 线程不安全
  • 根据插入/访问顺序排序
HashMap和Hashtable的区别
  • HashMap 允许 key 和 value 为 null,Hashtable 不允许。
  • HashMap 的默认初始容量为 16,Hashtable 为 11。
  • HashMap 的扩容为原来的 2 倍,Hashtable 的扩容为原来的 2 倍加 1。
  • HashMap 是非线程安全的,Hashtable是线程安全的。
  • HashMap 的 hash 值重新计算过(jdk1.8 hash(key)),Hashtable 直接使用 hashCode。
  • HashMap 去掉了 Hashtable 中的 contains 方法。
  • HashMap 继承自 AbstractMap 类,Hashtable 继承自 Dictionary 类。
HashTable和ConCurrentHashMap的区别
  • ConcurrentHashMap是线程安全的HashMap的实现。
  • HashTable里使用的是synchronized关键字,这其实是对对象加锁,锁住的都是对象整体,当Hashtable的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间。
  • ConcurrentHashMap(jdk1.7)使用了分割,将一个map分成多个小的hashtable,对map的一部分进行上锁。保证同步的同时,有提高了性能。具体的put操作:先判断是否需要扩容,扩容整理后根据key.hashcode()找到对应的Segmentm,再往Segment中put键值对,这个时候put是加锁的,利用自旋锁去尝试获取锁,获取锁后判断key是否存在,存在就覆盖不存在就添加一个键值对。总之就是利用再入锁的方式锁住Segment,保证只有一个线程在操作Segment,这就相当于在HashMap中保证了只有一个线程在数组的一个位置中put,这就不会形成环形链表了。
  • ConcurrentHashMap(jdk1.8):将每个segment的分段锁ReentrantLock改为CAS+Synchronized。

参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值