Java容器概覽

前言

由於去廣州面試,已經好幾天沒有更新了,準備從這篇文章開始來回顧一下我所學的Java容器知識,首先對他們有一個大概的瞭解而後逐步深刻源碼來進行相關的分析。java

爲何須要有容器

不止Java中有本身的容器,其它開發語言也大都有本身實現的相關容器或者說集合。面試

在Java中,變量能夠有基本數據類型,對象,以及數組編程

int a = 5;
Person p = new Person();
int[] arr = new int[5];複製代碼

但隨着愈來愈複雜的業務的出現,這些簡單的數據類型已經不能知足業務的需求了,這時咱們就須要更爲複雜的數據結構來支撐咱們的業務實現並簡化開發人員的開發難度。api

舉個最簡單的例子,上面的 arr 數組長度爲5,可是當咱們如今須要往其中放置大於5個的元素呢?這時候就須要咱們從新建立一個數組並將原數組一個一個複製過去,對於開發人員來講是至關浪費時間的事,甚至一個不注意還可能出現數組越界的糟糕狀況產生致使程序崩潰。因此ArrayList的存在就是解決這種問題的,固然不侷限於此。數組

咱們若是是更復雜的數據結構呢?別擔憂,Java還幫咱們實現了諸如HashMap的key-value等等複雜的數據結構。安全

容器是什麼

容器主要包括 Collection 和 Map 兩種,Collection 存儲着對象的集合,而 Map 存儲着鍵值對(key-value)的映射表。
容器,就是能夠容納其餘Java對象的對象。Java Collections Framework(JCF)爲Java開發者提供了通用的容器,其始於JDK 1.2,優勢是:
  • 下降編程難度
  • 提升程序性能
  • 提升API間的互操做性
  • 下降學習難度
  • 下降設計和實現相關API的難度
  • 增長程序的重用性
Java容器裏只能放對象,對於基本類型(int, long, float, double等),須要將其包裝成對象類型後(Integer, Long, Float, Double等)才能放到容器裏。不少時候拆包裝和解包裝可以自動完成。這雖然會致使額外的性能和空間開銷,但簡化了設計和編程,使開發者可以直接使用一些複雜的數據結構而不須要本身實現。

Java容器可以容納任何類型的對象,這一點表面上是經過泛型機制完成,Java泛型不是什麼神奇的東西,只是編譯器爲咱們提供的一個「語法糖」,泛型自己並不須要Java虛擬機的支持,只須要在編譯階段作一下簡單的字符串替換便可。實質上Java的單繼承機制纔是保證這一特性的根本,由於全部的對象都是Object的子類,容器裏只要可以存放Object對象就好了。 事實上,全部容器的內部存放的都是Object對象,泛型機制只是簡化了編程,由編譯器自動幫咱們完成了強制類型轉換而已。JDK 1.4以及以前版本不支持泛型,類型轉換須要顯式完成。數據結構

Map


  • HashMap:基於哈希表實現。
  • HashTable:和 HashMap 相似,但它是線程安全的,這意味着同一時刻多個線程能夠同時寫入 HashTable 而且不會致使數據不一致。它是遺留類,不該該去使用它。如今可使用 ConcurrentHashMap 來支持線程安全,而且 ConcurrentHashMap 的效率會更高,由於 ConcurrentHashMap 引入了分段鎖。
  • LinkedHashMap:使用雙向鏈表來維護元素的順序,順序爲插入順序或者最近最少使用(LRU)順序。
  • TreeMap:基於紅黑樹實現,是有序的。

Collection


1. Set

  • TreeSet:基於紅黑樹實現,支持有序性操做,例如根據一個範圍查找元素的操做。可是查找效率不如 HashSet,HashSet 查找的時間複雜度爲 O(1),TreeSet 則爲 O(logN)。
  • HashSet:基於哈希表實現,支持快速查找,但不支持有序性操做。而且失去了元素的插入順序信息,也就是說使用 Iterator 遍歷 HashSet 獲得的結果是不肯定的。
  • LinkedHashSet:具備 HashSet 的查找效率,且內部使用雙向鏈表維護元素的插入順序。

2. List

  • ArrayList:基於動態數組實現,支持隨機訪問。
  • Vector:和 ArrayList 相似,但它是線程安全的。
  • LinkedList:基於雙向鏈表實現,只能順序訪問,可是能夠快速地在鏈表中間插入和刪除元素。不只如此,LinkedList 還能夠用做棧、隊列和雙向隊列。

3. Queue

  • LinkedList:能夠用它來實現雙向隊列。
  • PriorityQueue:基於堆結構實現,能夠用它來實現優先隊列。

各個Java容器適用的場景

List

可用於數據出現重複的場景,與普通類型的數組相似併發

  • ArrayList:底層實現爲數組,讀取元素時間複雜度爲O(1),適用於讀多的場景
  • LinkedList:底層實現爲鏈表,頭尾操做及插入指定位置簡單,適用於數據改變較多的場景
  • Vector:線程安全的ArrayList

Set

數據不重複的集合,可用於去重性能

  • HashSet:適用於對排序無要求的場景,且其get元素時間複雜度爲O(1)
  • TreeSet:適用於要排序的場景

Map

是key-value類型的鍵值對,可用於須要數據匹配的場景,如學生學號對應學生類實體學習

  • HashMap:key-value存取。
  • ConcurrentHashMap:HashMap在併發環境中會出現線程不安全問題,須要使用ConcurrentHashMap來保證線程安全。
  • TreeMap:適用於須要排序的key-value數據類型的場景。

小結

容器的簡單介紹到這裏就結束了,細心的話你可能會發現,這些容器與咱們學習的數據結構有些類似之處,其實他們的底層原理就是對相應的數據結構進行了組合與封裝,抽象出一套api供開發者使用。以後我會選取幾個經常使用的比較重要的容器進行更加深刻的分析,Java中的容器沒有好用與很差用之分,只有理解容器的底層的實現原理,才能更好地使用他們,並將他們用在合適的場景,發揮出最大的用處。

相關文章
相關標籤/搜索