参考文献 :/qq_25868207/article/details/55259978/LittleHann/p/3690187.html/p/047e33fdefd2
Java容器类类库的用途是"保存对象",并将其划分为两个不同的概念:1) Collection一组"对立"的元素,通常这些元素都服从某种规则1.1) List必须保持元素特定的顺序1.2) Set不能有重复元素1.3) Queue保持一个队列(先进先出)的顺序2) Map一组成对的"键值对”对象
Collection和Map的区别在于容器中每个位置保存的元素个数:1) Collection 每个位置只能保存一个元素(对象)2) Map保存的是"键值对",就像一个小型数据库。我们可以通过"键"找到该键对应的"值"
ArrayList要点概括:1.ArrayList是List接口的可变数组非同步实现,并允许包括null在内的所有元素。2.底层使用数组实现3.该集合是可变长度数组,数组扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量增长大约是其容量的1.5倍,这种操作的代价很高。4.采用了Fail-Fast机制,面对并发的修改时,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险5.remove方法会让下标到数组末尾的元素向前移动一个单位,并把最后一位的值置空,方便GC
LinkedList要点概括:1.LinkedList是List接口的双向链表非同步实现,并允许包括null在内的所有元素。2.底层的数据结构是基于双向链表的,该数据结构我们称为节点3.双向链表节点对应的类Node的实例,Node中包含成员变量:prev,next,item。其中,prev是该节点的上一个节点,next是4.该节点的下一个节点,item是该节点所包含的值。5.它的查找是分两半(二分)查找,先判断index是在链表的哪一半,然后再去对应区域查找,这样最多只要遍历链表的一半节点即可找到
HashSet要点概括1.HashSet由哈希表(实际上是一个HashMap实例)支持,不保证set的迭代顺序,并允许使用null元素。2.基于HashMap实现,API也是对HashMap的行为进行了封装,可参考HashMap
LinkedHashSet 要点概括对于LinkedHashSet而言,它继承与HashSet、又基于LinkedHashMap来实现的。LinkedHashSet底层使用LinkedHashMap来保存所有元素,它继承与HashSet,其所有的方法操作上又与HashSet相同。
HashTable要点概括1.Hashtable是基于哈希表的Map接口的同步实现,不允许使用null值和null键2.底层使用数组实现,数组中每一项是个单链表,即数组和链表的结合体3.Hashtable在底层将key-value当成一个整体进行处理,这个整体就是一个Entry对象。Hashtable底层采用一个Entry[]数组来保存所有的key-value对,当需要存储一个Entry对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry。4.synchronized是针对整张Hash表的,即每次锁住整张表让线程独占
HashMap 要点概括1.HashMap是基于哈希表的Map接口的非同步实现,允许使用null值和null键,但不保证映射的顺序。底层使用数组实现,数组中每一项是个单向链表,即数组和链表的结合体;当链表长度大于一定阈值时,链表转换为红黑树,这样减少链表查询时间。2.HashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Node对象。HashMap底层采用一个Node[]数组来保存所有的key-value对,当需要存储一个Node对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法3.决定其在该数组位置上的链表中的存储位置;当需要取出一个Node时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Node。4.HashMap进行数组扩容需要重新计算扩容后每个元素在数组中的位置,很耗性能5.采用了Fail-Fast机制,通过一个modCount值记录修改次数,对HashMap内容的修改都将增加这个值。迭代器初始化过程中会将这个值赋给迭代器的expectedModCount,在迭代过程中,判断modCount跟expectedModCount是否相等,如果不相等就表示已经有其他线程修改了Map,马上抛出异常
ConcurrentHashMap要点概括ConcurrentHashMap是线程安全且高效的HashMap。多线程环境下,使用非线程安全的HashMap会导致死循环,而如文章中建议的那样,HashTable这种过时容器效率低下(使用synchronized来保证线程安全)。ConcurrentHashMap使用锁分段技术,大大提高了并发使用的效率。
锁分段技术: 假设容器有多把锁,每一把锁用于锁容器其中一部分数据,当多线程访问容器不同数据段数据时,线程间就不存在锁竞争,从而提高并发访问效率。1.ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术。它使用了多个锁来控制对hash表的不同段进行的修改,每个段其实就是一个小的hashtable,它们有自己的锁。只要多个并发发生在不同的段上,它们就可以并发进行。2.ConcurrentHashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Entry对象。Hashtable底层采用一个Entry[]数组来保存所有的key-value对,当需要存储一个Entry对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry。3.与HashMap不同的是,ConcurrentHashMap使用多个子Hash表,也就是段(Segment)4.ConcurrentHashMap完全允许多个读操作并发进行,读操作并不需要加锁。如果使用传统的技术,如HashMap中的实现,如果允许可以在hash链的中间添加或删除元素,读操作不加锁将得到不一致的数据。ConcurrentHashMap实现技术是保证HashEntry几乎是不可变的
LinkedHashMap 要点概括1.LinkedHashMap继承于HashMap,底层使用哈希表和双向链表来保存所有元素,并且它是非同步,允许使用null值和null键。2.基本操作与父类HashMap相似,通过重写HashMap相关方法,重新定义了数组中保存的元素Entry,来实现自己的链接列表特性。该Entry除了保存当前对象的引用外,还保存了其上一个元素before和下一个元素after的引用,从而构成了双向链接列表。