Java集合框架

来源:互联网 发布:淘宝客鹊桥助手 编辑:程序博客网 时间:2024/06/18 14:38

      Java集合框架包括很多集合类:

      List: ArrayList, LinkedList, Vector, Stack
      Set: HashSet, LinkedHashSet, TreeSet
      Queue: PriorityQueue, ArrayDeque
      Map: HashMap, LinkedHashMap, TreeMap, HashTable, WeakHashMap

      并发 
      List: CopyOnWriteArrayList
      Set: CopyOnWriteArraySet, ConCurrentSkipListSet
      Queue: ArrayBlockingQueue, LinkedBlockingQueue, DelayQueue, PriorityBlockingQueue, SynchronousQueue,             ConcurrentLinkedQueue
      Map: ConcurrentHashMap, ConcurrentSkipListMap

      Collections: synchronizedList, synchronizedMap, synchronizedSet, synchronizedSortedMap, synchronizedSortedSet,     synchronizedNavigableMap, synchronizedNavigableSet

      下面介绍各个类的具体内容。

①ArrayList

      底层实现:数组
      初始容量:10
      扩容:1.5倍。因为如果一次扩容太大,可能会浪费更多的内存,而如果一次性扩容太小,需要多次对数组重新分配内存,对性能消耗比较严重。
      modCount作用:在多线程操作过程中发现modCount不一致并抛出错误,即fail-fast机制。

②LinkedList

      底层实现:双向链表

③Vector

      底层实现:数组
      初始容量:10
      扩容:2倍。可指定扩容增量。
      线程安全
      对于 Vector 整个的扩容过程,就是根据 capacityIncrement 确认扩容大小的,若 capacityIncrement <= 0 则扩大一倍,否则扩大至 capacityIncrement 。当然这个容量的最大范围为 Integer.MAX_VALUE即,2^32 – 1,所以 Vector 并不是可以无限扩充的。

④stack

      底层实现:继承Vector
      线程安全

⑤HashMap

      底层实现:数组+列表
      初始容量:16
      默认加载因子:0.75
      扩容:2倍
      线程不安全
      容量表示哈希表中桶的数量,初始容量是创建哈希表时的容量,加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度,它衡量的是一个散列表的空间的使用程度,负载因子越大表示散列表的装填程度越高,反之愈小。

      查找一个元素的平均时间是 O(1+a),因此如果负载因子越大,对空间的利用更充分,然而后果是查找效率的降低;如果负载因子太小,那么散列表的数据将过于稀疏,对空间造成严重浪费。

       HashMap 保存数据的过程为:当我们向一个 HashMap 中添加一对 key-value 时,系统首先会计算 key 的 hash 值,然后根据 hash 值确认在 table 中存储的位置。若该位置没有元素,则直接插入。否则迭代该处元素链表并依此比较其 key 的 hash 值。如果两个 hash 值相等且 key 值相等 (e.hash == hash && ((k = e.key) == key || key.equals(k))),则用新的 Entry 的 value 覆盖原来节点的 value。如果两个 hash 值相等但 key 值不等 ,则将该节点插入该链表的链头
HashMap的初始容量总设为2的n次方, 是因为当 length = 2^n 时,不同的 hash 值发生碰撞的概率比较小,这样就会使得数据在 table 数组中分布较均匀,查询速度也较快。

⑥HashSet

      底层实现:基于HaspMap
      HashSet 中的所有元素都是保存在 HashMap 的 key 中,value 则是使用的 PRESENT 对象,该对象为 static final。

⑦HashTable

      底层实现:
      初始容量:11
      加载因子:0.75
      扩容:2倍+1
      线程安全
      put 方法的整个处理流程是:计算 key 的 hash 值,根据 hash 值获得 key 在 table 数组中的索引位置,然后迭代该 key 处的 Entry 链表(我们暂且理解为链表),若该链表中存在一个这个的 key 对象,那么就直接替换其 value 值即可,否则在将改 key-value 节点插入该 index 索引位置处。


HashMap和HashTable的区别:

      (1)HashMap是非线程安全的,HashTable是线程安全的。
      (2)HashMap允许key和value可以为null,而HashTable不允许。
      (3)由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。
      (4)HashMap不能保证随着时间的推移Map中的元素次序是不变的。
      (5)HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。
      (6)容量和扩容大小都不一致。

⑧LinkedHashMap

      底层实现:散列表+双向链表
      非线程安全
      LinkedHashMap 是 HashMap 的一个子类,它保留插入的顺序,如果需要输出的顺序和输入时的相同,那么就选用 LinkedHashMap。




原创粉丝点击