最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java集合中List與Set的區(qū)別及體系全覽

 更新時(shí)間:2026年05月28日 09:00:14   作者:身如柳絮隨風(fēng)揚(yáng)  
在 Java 開(kāi)發(fā)中,集合(Collection)是最常用的工具之一,本文將帶你從頂層 Collection 接口出發(fā),全面梳理 Java 集合體系的繼承關(guān)系,并深入對(duì)比 List 與 Set 的核心差異,希望對(duì)大家有所幫助

1. 引言

在 Java 開(kāi)發(fā)中,集合(Collection)是最常用的工具之一。無(wú)論是存儲(chǔ)一組對(duì)象、遍歷數(shù)據(jù),還是進(jìn)行去重、排序操作,都離不開(kāi) ListSet 等集合接口。然而,很多初學(xué)者對(duì)集合的整體架構(gòu)一知半解,對(duì)于 “List 是有序、可重復(fù)的;Set 是無(wú)序、不可重復(fù)的” 只停留在死記硬背,并不理解其底層原理和適用場(chǎng)景。

本文將帶你從頂層 Collection 接口出發(fā),全面梳理 Java 集合體系的繼承關(guān)系,并深入對(duì)比 ListSet 的核心差異,配合 UML 類(lèi)圖和流程圖,讓你徹底搞懂:

  • 集合框架的整體結(jié)構(gòu)(List、Set 兩大分支)
  • ArrayList、LinkedList、Vector 的區(qū)別與選型
  • HashSet、TreeSet 的底層實(shí)現(xiàn)與排序機(jī)制
  • 有序/無(wú)序重復(fù)/不重復(fù) 的真正含義
  • 如何根據(jù)業(yè)務(wù)場(chǎng)景選擇合適的集合

2. 集合體系全景圖(UML 類(lèi)圖)

Java 集合框架的根接口是 Collection,它派生出兩大核心分支:ListSet。下面是簡(jiǎn)化的繼承關(guān)系圖:

說(shuō)明

  • List 接口:有序、可重復(fù)、有索引。
  • Set 接口:無(wú)序(或特定順序)、不可重復(fù)、無(wú)索引。
  • 虛線箭頭表示實(shí)現(xiàn)接口,實(shí)線箭頭表示繼承。

3. List:有序可重復(fù)的序列

List 代表一個(gè)有序集合(Ordered Collection),即元素按照插入順序排列,并且可以包含重復(fù)元素。每個(gè)元素都有一個(gè)整數(shù)索引,可以精確訪問(wèn)。

3.1 List 的核心特性

特性描述
有序性迭代順序 = 插入順序(除非手動(dòng)排序)。
可重復(fù)性允許存儲(chǔ) e1.equals(e2) == true 的元素。
索引訪問(wèn)提供 get(int index)、set(int index, E element) 等方法。
遍歷方式for 循環(huán)、增強(qiáng) for、Iterator、ListIterator。

3.2 常用實(shí)現(xiàn)類(lèi)對(duì)比

實(shí)現(xiàn)類(lèi)底層數(shù)據(jù)結(jié)構(gòu)隨機(jī)訪問(wèn)增刪效率線程安全適用場(chǎng)景
ArrayList動(dòng)態(tài)數(shù)組O(1)尾部 O(1),中間 O(n)查詢(xún)多、增刪少
LinkedList雙向鏈表O(n)頭部/尾部 O(1),中間 O(n)頻繁頭尾增刪
Vector動(dòng)態(tài)數(shù)組(同步)O(1)尾部 O(1),中間 O(n)(但落后)已過(guò)時(shí),不建議使用

示例

List<String> arrayList = new ArrayList<>();
arrayList.add("A"); // 尾部插入
arrayList.add(0, "B"); // 中間插入,元素后移

List<String> linkedList = new LinkedList<>();
linkedList.addFirst("head");
linkedList.addLast("tail");

選型建議

  • 大多數(shù)場(chǎng)景用 ArrayList,因?yàn)閷?shí)際查詢(xún)需求遠(yuǎn)多于中間插入。
  • 如果需要線程安全的 List,使用 Collections.synchronizedList()CopyOnWriteArrayList(JUC 包)。

4. Set:不重復(fù)的集合

Set 接口代表一個(gè)不包含重復(fù)元素的集合。數(shù)學(xué)上集合的特性——互異性——在 Java 中通過(guò) equals()hashCode() 實(shí)現(xiàn)。

4.1 Set 的核心特性

特性描述
不可重復(fù)性set.add(e) 時(shí),如果 e 已存在(根據(jù) equals 比較),則插入失敗。
無(wú)序性(部分實(shí)現(xiàn))HashSet 不保證順序;LinkedHashSet 按插入順序;TreeSet 按自然順序或比較器排序。
無(wú)索引無(wú)法通過(guò)下標(biāo)訪問(wèn),只能通過(guò)迭代器或增強(qiáng) for 遍歷。
常用操作并集、交集、差集等集合運(yùn)算。

4.2 常用實(shí)現(xiàn)類(lèi)對(duì)比

實(shí)現(xiàn)類(lèi)底層結(jié)構(gòu)排序允許 null線程安全使用場(chǎng)景
HashSetHashMap無(wú)(哈希散列)一個(gè) null最快去重,不關(guān)心順序
LinkedHashSetLinkedHashMap插入順序一個(gè) null去重并保持插入順序
TreeSetTreeMap(紅黑樹(shù))自然順序/定制順序不允許 null(默認(rèn))需要排序去重

示例

Set<String> hashSet = new HashSet<>();
hashSet.add("banana");
hashSet.add("apple");
hashSet.add("banana");
System.out.println(hashSet); // 無(wú)序,可能 [banana, apple]

Set<String> treeSet = new TreeSet<>();
treeSet.add("banana");
treeSet.add("apple");
System.out.println(treeSet); // [apple, banana] 按字典序

Set<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("banana");
linkedHashSet.add("apple");
System.out.println(linkedHashSet); // [banana, apple] 插入順序

注意

  • HashSet 的“無(wú)序” ≠ 隨機(jī)順序,而是指迭代順序與插入順序無(wú)關(guān)(依賴(lài)哈希分布)。
  • 自定義對(duì)象放入 HashSet/TreeSet 時(shí)必須重寫(xiě) equals()hashCode()HashSet)或?qū)崿F(xiàn) Comparable/提供 ComparatorTreeSet)。

5. List vs Set:核心區(qū)別圖解

5.1 對(duì)比表格

維度ListSet
順序保證插入順序一般無(wú)序(除 LinkedHashSet、TreeSet
重復(fù)允許重復(fù)不允許重復(fù)
索引有索引(通過(guò)整數(shù)訪問(wèn))無(wú)索引,只能通過(guò)迭代器或增強(qiáng) for
常用實(shí)現(xiàn)ArrayList, LinkedList, VectorHashSet, LinkedHashSet, TreeSet
典型場(chǎng)景需要保持順序、可能需要重復(fù)、根據(jù)位置訪問(wèn)去重、集合運(yùn)算、自動(dòng)排序
性能(查找)隨機(jī)訪問(wèn) O(1)(數(shù)組),鏈表 O(n)HashSet O(1),TreeSet O(log n)
允許 null允許任意多個(gè) null最多一個(gè) null(TreeSet 不允許)

5.2 代碼對(duì)比示例

// List 可以重復(fù)
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(1);
System.out.println(list.size()); // 2

// Set 自動(dòng)去重
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(1);
System.out.println(set.size()); // 1

6. 如何選擇 List 還是 Set?

決策要點(diǎn)

  • 如果元素必須按某個(gè)特定順序(如用戶(hù)操作日志),用 List。
  • 如果業(yè)務(wù)要求元素唯一(如用戶(hù)ID集合),用 Set。
  • 如果既需要去重又需要保持插入順序,用 LinkedHashSet。
  • 如果既需要去重又需要自動(dòng)排序,用 TreeSet。

7. 常見(jiàn)面試題

Q1: 為什么HashSet不保證順序,而LinkedHashSet可以?

因?yàn)?HashSet 底層使用 HashMap,元素的存儲(chǔ)位置由哈希碼決定,插入順序無(wú)法保留。LinkedHashSetHashMap 基礎(chǔ)上額外維護(hù)了一個(gè)雙向鏈表,記錄了插入順序,因此迭代時(shí)按插入順序輸出。

Q2:ArrayList和LinkedList誰(shuí)的內(nèi)存占用更大?

LinkedList 每個(gè)節(jié)點(diǎn)需要存儲(chǔ)前驅(qū)和后繼引用,額外內(nèi)存開(kāi)銷(xiāo)比 ArrayList 大。ArrayList 底層數(shù)組會(huì)有一定的容量預(yù)留(擴(kuò)容策略),也可能存在空間浪費(fèi)。總體而言,元素?cái)?shù)量較多時(shí) ArrayList 內(nèi)存效率更高。

Q3:Vector已經(jīng)過(guò)時(shí),為什么還在某些舊項(xiàng)目中出現(xiàn)?

Vector 是 JDK 1.0 就存在的線程安全 List,方法使用 synchronized 修飾,性能較差。Java 1.2 引入 ArrayList 后,Vector 被標(biāo)記為遺留類(lèi)。如需線程安全,推薦使用 Collections.synchronizedListCopyOnWriteArrayList。

Q4: 可以將Set轉(zhuǎn)換為L(zhǎng)ist嗎?

可以,List 構(gòu)造函數(shù)可以接收任何 Collection

Set<String> set = new HashSet<>(Arrays.asList("A", "B"));
List<String> list = new ArrayList<>(set);
// 之后可對(duì) list 排序、索引訪問(wèn)等

8. 總結(jié)

  • List:有序、可重復(fù)、有索引,適合需要按照插入順序訪問(wèn)或根據(jù)位置操作的場(chǎng)景。
  • Set:無(wú)序(或特定順序)、不可重復(fù)、無(wú)索引,適合去重和集合運(yùn)算。
  • 選擇集合時(shí),優(yōu)先考慮元素是否唯一、順序要求、訪問(wèn)模式。
  • 熟悉底層數(shù)據(jù)結(jié)構(gòu)(數(shù)組、鏈表、哈希表、紅黑樹(shù))有助于理解性能差異。

記憶口訣

List 排隊(duì)可重復(fù),Set 唯一不重復(fù)。

索引增刪看實(shí)現(xiàn),Hash 最快 Tree 排序。

到此這篇關(guān)于Java集合中List與Set的區(qū)別及體系全覽的文章就介紹到這了,更多相關(guān)Java集合List與Set區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Activiti如何啟動(dòng)流程并使流程前進(jìn)

    Activiti如何啟動(dòng)流程并使流程前進(jìn)

    這篇文章主要介紹了Activiti如何啟動(dòng)流程并使流程前進(jìn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • java  中Excel轉(zhuǎn)shape file的實(shí)例詳解

    java 中Excel轉(zhuǎn)shape file的實(shí)例詳解

    這篇文章主要介紹了java 中Excel轉(zhuǎn)shape file的實(shí)例詳解的相關(guān)資料,希望通過(guò)本文大家能實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下
    2017-09-09
  • JAVA數(shù)組練習(xí)題實(shí)例講解

    JAVA數(shù)組練習(xí)題實(shí)例講解

    這篇文章主要給大家介紹了關(guān)于JAVA數(shù)組練習(xí)題的相關(guān)資料,這是個(gè)人總結(jié)的一些關(guān)于java數(shù)組的練習(xí)題,文中通過(guò)代碼實(shí)例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • Java實(shí)現(xiàn)支付寶之第三方支付寶即時(shí)到賬支付功能

    Java實(shí)現(xiàn)支付寶之第三方支付寶即時(shí)到賬支付功能

    這篇文章主要介紹了Java實(shí)現(xiàn)支付寶之第三方支付寶即時(shí)到賬支付功能的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • springboot項(xiàng)目中controller層與前端的參數(shù)傳遞方式

    springboot項(xiàng)目中controller層與前端的參數(shù)傳遞方式

    這篇文章主要介紹了springboot項(xiàng)目中controller層與前端的參數(shù)傳遞方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Java DelayQueue延遲隊(duì)列的原理與應(yīng)用場(chǎng)景詳解

    Java DelayQueue延遲隊(duì)列的原理與應(yīng)用場(chǎng)景詳解

    DelayQueue是一個(gè)無(wú)界阻塞隊(duì)列,里面裝滿(mǎn)了實(shí)現(xiàn)Delayed接口的元素,本文主要為大家詳細(xì)介紹了Java如何使用DelayQueue,感興趣的小伙伴可以了解下
    2025-07-07
  • idea替換快捷鍵,批量處理對(duì)象的操作

    idea替換快捷鍵,批量處理對(duì)象的操作

    這篇文章主要介紹了idea替換快捷鍵,批量處理對(duì)象的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • Go Java算法之從英文中重建數(shù)字示例詳解

    Go Java算法之從英文中重建數(shù)字示例詳解

    這篇文章主要為大家介紹了Go Java算法之從英文中重建數(shù)字示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • SpringBoot整合RabbitMQ實(shí)現(xiàn)延遲隊(duì)列和死信隊(duì)列

    SpringBoot整合RabbitMQ實(shí)現(xiàn)延遲隊(duì)列和死信隊(duì)列

    RabbitMQ的死信隊(duì)列用于接收其他隊(duì)列中的“死信”消息,所謂“死信”,是指滿(mǎn)足一定條件而無(wú)法被消費(fèi)者正確處理的消息,死信隊(duì)列通常與RabbitMQ的延遲隊(duì)列一起使用,本文給大家介紹了SpringBoot整合RabbitMQ實(shí)現(xiàn)延遲隊(duì)列和死信隊(duì)列,需要的朋友可以參考下
    2024-06-06
  • 詳解Springboot整合ActiveMQ(Queue和Topic兩種模式)

    詳解Springboot整合ActiveMQ(Queue和Topic兩種模式)

    這篇文章主要介紹了詳解Springboot整合ActiveMQ(Queue和Topic兩種模式),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04

最新評(píng)論

香港 | 香港 | 昔阳县| 刚察县| 大冶市| 琼结县| 龙井市| 赣州市| 临朐县| 南丰县| 西昌市| 孝昌县| 新乡市| 阳新县| 大丰市| 安义县| 阿巴嘎旗| 溧阳市| 宜春市| 通化市| 鄂尔多斯市| 开远市| 稻城县| 即墨市| 中宁县| 洛阳市| 滦平县| 铅山县| 高台县| 绩溪县| 沙河市| 建瓯市| 朔州市| 宜丰县| 巫山县| 翼城县| 安仁县| 萨迦县| 方正县| 星子县| 贵港市|