目錄
前言:
一、List接口
1.1 ArrayList
1.2 LinkedList
1.3 Vector
二、Set接口
2.1 HashSet
2.2 TreeSet
2.3 LinkedHashSet
三、應用選擇
前言:
本篇文章重點梳理 List 接口和 Set 接口的核心內容,結合代碼案例幫大家吃透它們的特點和用法。
先簡單復習下 Collection 接口:它是所有單列集合的 “老祖宗”,定義了添加、刪除、判斷包含等通用方法,像add()、remove()、contains()這些,咱們后面講的 List 和 Set 都能直接用。
一、List接口
------有序、可重復、帶索引的 “排隊隊伍”
List 接口繼承了 Collection,就像在 Collection 的基礎上多了些 “特殊技能”。咱們記住它的三個核心特點:
--有序:元素怎么存進去,取出來還是這個順序,比如存[1,2,3],取出來不會變成[3,1,2];
--帶索引:可以通過下標(0、1、2...)直接訪問元素,就像數組那樣用get(index)拿值;
--可重復:同一個元素能存多次,比如list.add("a"); list.add("a");會有兩個 "a"。
List接口有三種實現類:ArrayList、LinkedList、Vector。
1.1 ArrayList
------查詢快、增刪慢的 “數組加強版”
ArrayList 是 List 最常用的實現類,底層就是個動態數組(長度能自動變)
- 優點:查詢快!因為數組在內存中連續存儲,通過索引直接定位,時間復雜度 O (1);
- 缺點:增刪慢!如果在中間插元素,后面的元素都得往后挪,比如數組
[1,2,3]
插個 4 到中間,就變成[1,4,2,3]
,2 和 3 都要移動。
代碼案例:
List<String> list = new ArrayList<>();
list.add("蘋果"); // 末尾加元素
list.add(1, "香蕉"); // 下標1的位置插入
System.out.println(list.get(0)); // 用索引查元素,輸出“蘋果”
list.remove(1); // 刪除下標1的元素
1.2 LinkedList
------增刪快、查詢慢的 “鏈表”
LinkedList 底層是雙向鏈表,每個元素像個 “小火車車廂”,除了存數據,還帶著前后 “鉤子”(指針)
- 優點:增刪快!中間插元素只需改前后指針,不用移動其他元素,比如鏈表
1->2->3
插個 4,改成1->4->2->3
就行; - 缺點:查詢慢!找第 n 個元素得從第一個開始挨個往后數,時間復雜度 O (n)。
代碼案例:
LinkedList<String> list = new LinkedList<>();
list.addFirst("頭"); // 頭部加元素
list.addLast("尾"); // 尾部加元素
System.out.println(list.getFirst()); // 取頭部元素
list.removeLast(); // 刪除尾部元素
1.3 Vector
------線程安全的 “老古董”
Vector 和 ArrayList 類似,也是動態數組,但它的方法大多加了synchronized(同步鎖),多線程環境下用著安全。不過單線程下性能不如 ArrayList,現在基本被Collections.synchronizedList(new ArrayList<>())替代了。
二、Set接口
------無序、不可重復的 “聚寶盆”
Set 接口也是 Collection 的 “孩子”,但和 List 性格完全不同:
--無序:存的順序和取的順序沒關系(LinkedHashSet 除外);
--無索引:不能用下標訪問,只能遍歷;
--不可重復:相同元素只能存一次,比如set.add("a"); set.add("a");最終只有一個 "a"。
2.1 HashSet
------用哈希表實現的 “去重小能手”
HashSet 底層是哈希表,判斷元素是否重復靠兩個方法:
hashCode()
和equals()
--存元素時,先算元素的哈希值(hashCode()),找對應的 “坑位”;
--如果 “坑位” 已有元素,再用equals()比較,相同就不存,不同就 “掛” 在后面(哈希沖突處理)。
代碼案例:
Set<String> set = new HashSet<>();
set.add("張三");
set.add("張三"); // 重復,添加失敗
set.add(null);
set.add(null); // 重復,只存一個null
System.out.println(set.size()); // 輸出2("張三"和null)
注意:
存自定義對象(比如 Student)時,必須重寫hashCode()和equals(),否則去重失效!
2.2 TreeSet
------自動排序的 “整理小助手”
TreeSet 底層是紅黑樹(一種排序樹),元素會自動按規則排好序。
排序規則有兩種:
--自然排序:元素類實現Comparable接口,重寫compareTo()方法;
--比較器排序:創建 TreeSet 時傳Comparator對象,自定義排序邏輯。
代碼案例:
????????--自然排序
// Student類實現Comparable接口
class Student implements Comparable<Student> {String name;int age;@Overridepublic int compareTo(Student o) {return this.age - o.age; // 按年齡升序}
}Set<Student> set = new TreeSet<>();
set.add(new Student("張三", 20));
set.add(new Student("李四", 18));
// 遍歷會輸出:李四(18)、張三(20)(按年齡排好了)
2.3 LinkedHashSet
------有序的 “HashSet 升級版”
LinkedHashSet 是 HashSet 的子類,底層多了個鏈表記錄插入順序,所以既能去重,又能保證 “存啥順序,取啥順序”。性能比 HashSet 稍差,但在需要順序的時候很有用。
代碼案例:
Set<String> set = new LinkedHashSet<>();
set.add("b");
set.add("a");
set.add("c");
// 遍歷輸出:b、a、c(和插入順序一致)
三、應用選擇
有序用 List,去重用 Set;查多用 ArrayList,增刪多用 LinkedList;需要排序用 TreeSet,要順序去重用 LinkedHashSet。
總結:
集合 | 特點 | 場景舉例 |
---|---|---|
ArrayList | 查快增刪慢、有序重復 | 存班級名單,頻繁查詢 |
LinkedList | 增刪快查慢、有序重復 | 實現隊列 / 棧,頻繁加減元素 |
HashSet | 無序去重、效率高 | 存用戶 ID,需要去重 |
TreeSet | 自動排序、去重 | 存成績,需要按分數排序 |
LinkedHashSet | 有序去重 | 存操作日志,保留順序 |
好了,我們今天的內容就到這里了,感謝大家的觀看。