List 繼承 Collection,保留插入順序,允許 null 元素。常用實現:
Deque 可作棧/隊列。| 方法 | 說明 | 時間複雜度 |
|---|---|---|
addFirst(e) / addLast(e) | 頭部/尾部插入 | O(1) |
removeFirst() / removeLast() | 移除並返回頭/尾元素 | O(1) |
getFirst() / getLast() | 獲取但不移除頭/尾元素 | O(1) |
push(e) / pop() | 棧操作(等同 addFirst/removeFirst) | O(1) |
offer(e) / poll() | 隊列操作(尾部入隊/頭部出隊) | O(1) |
LinkedList<String> list = new LinkedList<>();
list.add("a"); list.add("b"); list.add("a");
list.addFirst("0"); list.addLast("9"); // [0, a, b, a, 9]
System.out.println(list);
list.removeLast(); // [0, a, b, a]
list.removeFirst(); // [a, b, a]
System.out.println(list.getFirst()); // a
System.out.println(list.getLast()); // a
System.out.println(list.isEmpty()); // false
Set 不保證順序(LinkedHashSet 除外),核心契約:e1.equals(e2) == true 則 e1.hashCode() == e2.hashCode() 必須成立。
底層由 HashMap 支撐,存入元素即作為 Key,Value 為固定 PRESENT 對象。自定義類型必須重寫 equals() 與 hashCode(),否則無法正確去重。
public class Person {
private String name; private int age;
// getter/setter/構造器省略
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override public int hashCode() { return Objects.hash(name, age); }
@Override public String toString() { return "Person{name='" + name + "', age=" + age + '}'; }
}
HashSet<Person> set = new HashSet<>();
set.add(new Person("張三", 12));
set.add(new Person("李四", 12));
set.add(new Person("張三", 12)); // 重複,不添加
set.add(new Person("張三", 21)); // 年齡不同,視為不同元素
set.forEach(System.out::println);
// 輸出(順序不固定):
// Person{name='張三', age=12}
// Person{name='李四', age=12}
// Person{name='張三', age=21}
底層 LinkedHashMap,維護雙向鏈表記錄插入順序,遍歷輸出與 add 順序一致,性能略低於 HashSet。
LinkedHashSet<String> lhs = new LinkedHashSet<>();
lhs.add("a"); lhs.add("b"); lhs.add("c"); lhs.add("d");
lhs.forEach(s -> System.out.print(s + " ")); // a b c d
元素需實現 Comparable 或提供 Comparator,按自然序或定製序排序,查找/插入/刪除 O(log n)。
| 需求 | 推薦實現 | 備註 |
|---|---|---|
| 高頻隨機訪問、尾部增刪 | ArrayList | 預估大小可指定 initialCapacity 避免擴容 |
| 高頻頭尾增刪、棧/隊列 | LinkedList | 避免隨機訪問 |
| 純去重、性能優先 | HashSet | 需正確實現 equals/hashCode |
| 去重 + 保持插入順序 | LinkedHashSet | LRU 緩存淘汰鏈表常用結構 |
| 去重 + 自動排序 | TreeSet | 範圍查詢、最近鄰搜索 |
掌握 List/Set 的底層數據結構、核心 API 及去重契約,是寫出高性能、低 Bug Java 代碼的基礎。實戰中根據「訪問模式、順序要求、去重邏輯」三維度選型,事半功倍。