Java 集合框架之Collection

来源:http://www.cnblogs.com/LeslieXia/archive/2016/08/14/5770330.html
-Advertisement-
Play Games

此圖是 java 中 Collection 相關的介面與類的關係的類圖。其中,類只是集合框架的一部分,比較常用的一部分。 第一次畫類圖,著實很費勁,不過收穫也不小。 下麵是相關介面和類的解釋說明。文字來自 JDK API 1.6 中文版。原諒我的懶惰,實在不想自己寫,太麻煩。如有錯誤,還請指正。 如 ...


     此圖是 java 中 Collection 相關的介面與類的關係的類圖。其中,類只是集合框架的一部分,比較常用的一部分。   第一次畫類圖,著實很費勁,不過收穫也不小。   下麵是相關介面和類的解釋說明。文字來自 JDK API 1.6 中文版。原諒我的懶惰,實在不想自己寫,太麻煩。如有錯誤,還請指正。   如圖,Set、Queue、List 介面都繼承自 Collection 介面。     

  AbstractCollection<E>

  此類提供 Collection 介面的骨幹實現,以最大限度地減少了實現此介面所需的工作。

  要實現一個不可修改的 collection,編程人員只需擴展此類,並提供 iterator 和 size 方法的實現。(iterator 方法返回的迭代器必須實現 hasNext 和 next。)

  要實現可修改的 collection,編程人員必須另外重寫此類的 add 方法(否則,會拋出 UnsupportedOperationException),iterator 方法返回的迭代器還必須另外實現其 remove 方法。

  按照 Collection 介面規範中的建議,編程人員通常應提供一個 void (無參數)和 Collection 構造方法。

 

  Set   一個不包含重覆元素的 collection。更確切地講,set 不包含滿足 e1.equals(e2) 的元素對 e1 和 e2,並且最多包含一個 null 元素。   註:如果將可變對象用作 set 元素,那麼必須極其小心。如果對象是 set 中某個元素,以一種影響 equals 比較的方式改變對象的值,那麼 set 的行為就是不確定的。此項禁止的一個特殊情況是不允許某個 set 包含其自身作為元素。    HashSet   此類實現 Set 介面,由哈希表(實際上是一個 HashMap 實例)支持。它不保證 set 的迭代順序;特別是它不保證該順序恆久不變。此類允許使用 null 元素。    此類為基本操作提供了穩定性能,這些基本操作包括 add、remove、contains 和 size,假定哈希函數將這些元素正確地分佈在桶中。對此 set 進行迭代所需的時間與 HashSet 實例的大小(元素的數量)和底層 HashMap 實例(桶的數量)的“容量”的和成比例。因此,如果迭代性能很重要,則不要將初始容量設置得太高(或將載入因數設置得太低)。   註意,此實現不是同步的。如果多個線程同時訪問一個哈希 set,而其中至少一個線程修改了該 set,那麼它必須 保持外部同步。這通常是通過對自然封裝該 set 的對象執行同步操作來完成的。如果不存在這樣的對象,則應該使用 Collections.synchronizedSet 方法來“包裝” set。最好在創建時完成這一操作,以防止對該 set 進行意外的不同步訪問:
  Set s = Collections.synchronizedSet(new HashSet(...));
  註意,迭代器的快速失敗行為無法得到保證,因為一般來說,不可能對是否出現不同步併發修改做出任何硬性保證。快速失敗迭代器在盡最大努力拋出 ConcurrentModificationException。因此,為提高這類迭代器的正確性而編寫一個依賴於此異常的程式是錯誤做法:迭代器的快速失敗行為應該僅用於檢測 bug。    LinkedHashSet   具有可預知迭代順序的 Set 介面的哈希表和鏈接列表實現。此實現與 HashSet 的不同之外在於,後者維護著一個運行於所有條目的雙重鏈接列表。此鏈接列表定義了迭代順序,即按照將元素插入到 set 中的順序(插入順序)進行迭代。註意,插入順序不 受在 set 中重新插入的 元素的影響。(如果在 s.contains(e) 返回 true 後立即調用 s.add(e),則元素 e 會被重新插入到 set s 中。)    此類提供所有可選的 Set 操作,並且允許 null 元素。與 HashSet 一樣,它可以為基本操作(add、contains 和 remove)提供穩定的性能,假定哈希函數將元素正確地分佈到存儲段中。由於增加了維護鏈接列表的開支,其性能很可能會比 HashSet 稍遜一籌,不過,這一點例外:LinkedHashSet 迭代所需時間與 set 的大小 成正比,而與容量無關。HashSet 迭代很可能支出較大,因為它所需迭代時間與其容量 成正比。    鏈接的哈希 set 有兩個影響其性能的參數:初始容量 和載入因數。它們與 HashSet 中的定義極其相同。註意,為初始容量選擇非常高的值對此類的影響比對 HashSet 要小,因為此類的迭代時間不受容量的影響。    註意,此實現不是同步的。如果多個線程同時訪問一個哈希 set,而其中至少一個線程修改了該 set,那麼它必須 保持外部同步。這通常是通過對自然封裝該 set 的對象執行同步操作來完成的。如果不存在這樣的對象,則應該使用 Collections.synchronizedSet 方法來“包裝” set。最好在創建時完成這一操作,以防止對該 set 進行意外的不同步訪問:
  Set s = Collections.synchronizedSet(new LinkedHashSet(...));
  註意,迭代器的快速失敗行為不能得到保證,一般來說,存在不同步的併發修改時,不可能作出任何強有力的保證。快速失敗迭代器盡最大努力拋出 ConcurrentModificationException。因此,編寫依賴於此異常的程式的方式是錯誤的,正確做法是:迭代器的快速失敗行為應該僅用於檢測程式錯誤。    TreeSet   基於 TreeMap 的 NavigableSet 實現。使用元素的自然順序對元素進行排序,或者根據創建 set 時提供的 Comparator 進行排序,具體取決於使用的構造方法。    此實現為基本操作(add、remove 和 contains)提供受保證的 log(n) 時間開銷。    註意,如果要正確實現 Set 介面,則 set 維護的順序(無論是否提供了顯式比較器)必須與 equals 一致。(關於與 equals 一致 的精確定義,請參閱 Comparable 或 Comparator。)這是因為 Set 介面是按照 equals 操作定義的,但 TreeSet 實例使用它的 compareTo(或 compare)方法對所有元素進行比較,因此從 set 的觀點來看,此方法認為相等的兩個元素就是相等的。即使 set 的順序與 equals 不一致,其行為也是 定義良好的;它只是違背了 Set 介面的常規協定。    註意,此實現不是同步的。如果多個線程同時訪問一個 TreeSet,而其中至少一個線程修改了該 set,那麼它必須 外部同步。這一般是通過對自然封裝該 set 的對象執行同步操作來完成的。如果不存在這樣的對象,則應該使用 Collections.synchronizedSortedSet 方法來“包裝”該 set。此操作最好在創建時進行,以防止對 set 的意外非同步訪問:
  Set s = Collections.synchronizedSet(new TreeSet(...));
  註意,迭代器的快速失敗行為無法得到保證,一般來說,存在不同步的併發修改時,不可能作出任何肯定的保證。快速失敗迭代器盡最大努力拋出 ConcurrentModificationException。因此,編寫依賴於此異常的程式的做法是錯誤的,正確做法是:迭代器的快速失敗行為應該僅用於檢測 bug。    CopyOnWriteArraySet   對其所有操作使用內部 CopyOnWriteArrayList 的 Set。因此,它共用以下相同的基本屬性:    1、它最適合於具有以下特征的應用程式:set 大小通常保持很小,只讀操作遠多於可變操作,需要在遍歷期間防止線程間的衝突。    2、它是線程安全的。   3、因為通常需要複製整個基礎數組,所以可變操作(add、set 和 remove 等等)的開銷很大。    4、迭代器不支持可變 remove 操作。    5、使用迭代器進行遍歷的速度很快,並且不會與其他線程發生衝突。在構造迭代器時,迭代器依賴於不變的數組快照。    ConcurrentSkipListSet   一個基於 ConcurrentSkipListMap 的可縮放併發 NavigableSet 實現。set 的元素可以根據它們的自然順序進行排序,也可以根據創建 set 時所提供的 Comparator 進行排序,具體取決於使用的構造方法。    此實現為 contains、add、remove 操作及其變體提供預期平均 log(n) 時間開銷。多個線程可以安全地併發執行插入、移除和訪問操作。迭代器是弱一致的,返回的元素將反映迭代器創建時或創建後某一時刻的 set 狀態。它們不拋出 ConcurrentModificationException,可以併發處理其他操作。升序排序視圖及其迭代器比降序排序視圖及其迭代器更快。    請註意,與在大多數 collection 中不同,這裡的 size 方法不是一個固定時間 (constant-time) 操作。由於這些 set 的非同步特性,確定元素的當前數目需要遍歷元素。此外,批量操作 addAll、removeAll、retainAll 和 containsAll 並不 保證能以原子方式 (atomically) 執行。例如,與 addAll 操作一起併發操作的迭代器只能查看某些附加元素。    此類及其迭代器實現 Set 和 Iterator 介面的所有可選方法。與大多數其他併發 collection 實現一樣,此類不允許使用 null 元素,因為無法可靠地將 null 參數及返回值與不存在的元素區分開來。     Queue   在處理元素前用於保存元素的 collection。除了基本的 Collection 操作外,隊列還提供其他的插入、提取和檢查操作。每個方法都存在兩種形式:一種拋出異常(操作失敗時),另一種返回一個特殊值(null 或 false,具體取決於操作)。插入操作的後一種形式是用於專門為有容量限制的 Queue 實現設計的;在大多數實現中,插入操作不會失敗。    隊列通常(但並非一定)以 FIFO(先進先出)的方式排序各個元素。不過優先順序隊列和 LIFO 隊列(或堆棧)例外,前者根據提供的比較器或元素的自然順序對元素進行排序,後者按 LIFO(後進先出)的方式對元素進行排序。無論使用哪種排序方式,隊列的頭 都是調用 remove() 或 poll() 所移除的元素。在 FIFO 隊列中,所有的新元素都插入隊列的末尾。其他種類的隊列可能使用不同的元素放置規則。每個 Queue 實現必須指定其順序屬性。    Queue 實現通常不允許插入 null 元素,儘管某些實現(如 LinkedList)並不禁止插入 null。即使在允許 null 的實現中,也不應該將 null 插入到 Queue 中,因為 null 也用作 poll 方法的一個特殊返回值,表明隊列不包含元素。    Queue 實現通常未定義 equals 和 hashCode 方法的基於元素的版本,而是從 Object 類繼承了基於身份的版本,因為對於具有相同元素但有不同排序屬性的隊列而言,基於元素的相等性並非總是定義良好的。    ConcurrentLinkedQueue   一個基於鏈接節點的無界線程安全隊列。此隊列按照 FIFO(先進先出)原則對元素進行排序。隊列的頭部 是隊列中時間最長的元素。隊列的尾部 是隊列中時間最短的元素。新的元素插入到隊列的尾部,隊列獲取操作從隊列頭部獲得元素。當多個線程共用訪問一個公共 collection 時,ConcurrentLinkedQueue 是一個恰當的選擇。此隊列不允許使用 null 元素。    記憶體一致性效果:當存在其他併發 collection 時,將對象放入 ConcurrentLinkedQueue 之前的線程中的操作 happen-before 隨後通過另一線程從 ConcurrentLinkedQueue 訪問或移除該元素的操作。      List   有序的 collection(也稱為序列)。此介面的用戶可以對列表中每個元素的插入位置進行精確地控制。用戶可以根據元素的整數索引(在列表中的位置)訪問元素,並搜索列表中的元素。   與 set 不同,列表通常允許重覆的元素。更確切地講,列表通常允許滿足 e1.equals(e2) 的元素對 e1 和 e2,並且如果列表本身允許 null 元素的話,通常它們允許多個 null 元素。難免有人希望通過在用戶嘗試插入重覆元素時拋出運行時異常的方法來禁止重覆的列表,但我們希望這種用法越少越好。   註意:儘管列表允許把自身作為元素包含在內,但建議要特別小心:在這樣的列表上,equals 和 hashCode 方法不再是定義良好的。   ArrayList   List 介面的大小可變數組的實現。實現了所有可選列表操作,並允許包括 null 在內的所有元素。除了實現 List 介面外,此類還提供一些方法來操作內部用來存儲列表的數組的大小。(此類大致上等同於 Vector 類,除了此類是不同步的。)   size、isEmpty、get、set、iterator 和 listIterator 操作都以固定時間運行。add 操作以分攤的固定時間 運行,也就是說,添加 n 個元素需要 O(n) 時間。其他所有操作都以線性時間運行(大體上講)。與用於 LinkedList 實現的常數因數相比,此實現的常數因數較低。   每個 ArrayList 實例都有一個容量。該容量是指用來存儲列表元素的數組的大小。它總是至少等於列表的大小。隨著向 ArrayList 中不斷添加元素,其容量也自動增長。並未指定增長策略的細節,因為這不只是添加元素會帶來分攤固定時間開銷那樣簡單。   在添加大量元素前,應用程式可以使用 ensureCapacity 操作來增加 ArrayList 實例的容量。這可以減少遞增式再分配的數量。   註意,此實現不是同步的  LinkedList   List 介面的鏈接列表實現。實現所有可選的列表操作,並且允許所有元素(包括 null)。除了實現 List 介面外,LinkedList 類還為在列表的開頭及結尾 get、remove 和 insert 元素提供了統一的命名方法。這些操作允許將鏈接列表用作堆棧、隊列或雙端隊列。   此類實現 Deque 介面,為 add、poll 提供先進先出隊列操作,以及其他堆棧和雙端隊列操作。   所有操作都是按照雙重鏈接列表的需要執行的。在列表中編索引的操作將從開頭或結尾遍歷列表(從靠近指定索引的一端)。   註意,此實現不是同步的  CopyOnWriteArrayList   ArrayList 的一個線程安全的變體,其中所有可變操作(add、set 等等)都是通過對底層數組進行一次新的複製來實現的。    這一般需要很大的開銷,但是當遍歷操作的數量大大超過可變操作的數量時,這種方法可能比其他替代方法更有效。在不能或不想進行同步遍歷,但又需要從併發線程中排除衝突時,它也很有用。“快照”風格的迭代器方法在創建迭代器時使用了對數組狀態的引用。此數組在迭代器的生存期內不會更改,因此不可能發生衝突,並且迭代器保證不會拋出 ConcurrentModificationException。創建迭代器以後,迭代器就不會反映列表的添加、移除或者更改。在迭代器上進行的元素更改操作(remove、set 和 add)不受支持。這些方法將拋出 UnsupportedOperationException。    允許使用所有元素,包括 null。    記憶體一致性效果:當存在其他併發 collection 時,將對象放入 CopyOnWriteArrayList 之前的線程中的操作 happen-before 隨後通過另一線程從 CopyOnWriteArrayList 中訪問或移除該元素的操作。    Vector   Vector 類可以實現可增長的對象數組。與數組一樣,它包含可以使用整數索引進行訪問的組件。但是,Vector 的大小可以根據需要增大或縮小,以適應創建 Vector 後進行添加或移除項的操作。    每個向量會試圖通過維護 capacity 和 capacityIncrement 來優化存儲管理。capacity 始終至少應與向量的大小相等;這個值通常比後者大些,因為隨著將組件添加到向量中,其存儲將按 capacityIncrement 的大小增加存儲塊。應用程式可以在插入大量組件前增加向量的容量;這樣就減少了增加的重分配的量。    Stack   Stack 類表示後進先出(LIFO)的對象堆棧。它通過五個操作對類 Vector 進行了擴展 ,允許將向量視為堆棧。它提供了通常的 push 和 pop 操作,以及取堆棧頂點的 peek 方法、測試堆棧是否為空的 empty 方法、在堆棧中查找項並確定到堆棧頂距離的 search 方法。    首次創建堆棧時,它不包含項。    Deque 介面及其實現提供了 LIFO 堆棧操作的更完整和更一致的 set,應該優先使用此 set,而非此類。例如:    
  Deque<Integer> stack = new ArrayDeque<Integer>();

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 參考了幾篇文章,和錯誤查詢,最後總結如下 一、下載 我比較傾向於使用mercurial來獲取源代碼,雖然你得挑網路穩定的時候更新,但是易更新。 從官網查找一下,可以通過以下步驟完成源代碼的下載 1. 其中java的版本可以上 http://hg.openjdk.java.net/ 自由選擇,路徑正確 ...
  • 一、page指令 page指令是最常用的指令,用來說明JSP頁面的屬性等。JSP指令的多個屬性可以寫在一個page指令里,也可以寫在多個指令里。但需要註意的是,無論在哪個page指令里的屬性,任何page允許的屬性都只能出現一次,否則會出現編譯錯誤。import屬性除外,可以出現多次。屬性名稱區分大 ...
  • 初學java EE,雖然知道使用框架會使開發更加便捷高效,但是對於初學者來說,感到使用框架比較迷惑,尤其是各種jar包的引用、各種框架的配置、註解的使用等等。 最好的學習方法就是實踐,於是下載了一個現成的DEMO,通過簡單的修改先成功在自己電腦上跑起來,然後再逐個文件進行分析學習,最終才能從總體的高 ...
  • SSM框架的Web程式主要用到了三個技術: 要完成一個功能: 簡單點就是: DataBase > Entity > Mapper.xml > Mapper.java > Service.java > Controller.java > Jsp. ...
  • 一共 15 篇隨筆,主要是為了記錄數據分析過程中的一些小 demo,分享給其他需要的網友,更為了方便以後自己查看,15 篇隨筆,每篇內容基本都是以一句說明加一段代碼的方式, 保持簡單小巧,看起來也清晰 ,一共可以劃分為三個大部分: 第一部分簡單介紹數據分析,以一個小例子簡單說明瞭什麼是數據分析和 I ...
  • --> List 列表中的自動添加的多餘空間長度該怎麼去除呢?... --> 還是沒有解決多餘空間的問題啊... ...
  • 目錄 什麼叫發佈 webapp發佈方式 reload 總結 什麼叫發佈 發佈就是讓tomcat知道我們的程式在哪裡,並根據我們的配置創建Context,進行初始化、啟動,如下: 程式所在的位置 創建Context,添加到Host 初始化(創建解析webxml的digester) 啟動(初始化filt ...
  • 一、Bean的生命周期 Spring IOC容器可以管理Bean的生命周期,允許在Bean生命周期的特定點執行定製的任務。 Spring IOC容器對Bean的生命周期進行管理的過程如下: (1).通過構造器或工廠方法創建Bean實例。 (2).為Bean的屬性設置值和對其它Bean的引用。 (3) ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...