首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

關於 Java Collections API 你不知道的 5 件事(第 2 部分)

     編輯:Java 相關知識

續集聚焦集合框架的進階陷阱與特性:List 與陣列語義差異、Iterator 隱藏能力、非集合 Iterable、可變鍵的 HashMap 陷阱、equals() 與 Comparable 的 Set 語義衝突。

1. List ≠ 陣列:順序 vs 位置

List 維護「插入順序」(Ordinal),刪除元素後續元素前移填補空位;陣列維護「固定位置」(Position),刪除實為覆蓋 null。

List list = new ArrayList<>(Arrays.asList("a","b","c"));
list.remove(1); // 刪除 "b",list 變為 ["a","c"],"c" 從位置2移到位置1
String[] arr = new String[]{"a","b","c"};
arr[1] = null;  // 陣列變為 ["a", null, "c"],位置不變

2. Iterator 隱藏超能力

  • 安全刪除:iterator.remove() 避免 ConcurrentModificationException
  • ListIterator 雙向游標:hasPrevious()、previous()、add()、set(),支援滑動結果集、反向遍歷

3. 非集合也能 Iterable

實現 Iterable 介面,iterator() 返回按需生成元素的 Iterator,可用增強 for 遍歷文件、資料庫結果、網絡流等無限序列。

public static Iterable readLines(String filename) {
    return () -> new Iterator() {
        String line = readFirstLine();
        public boolean hasNext() { return line != null; }
        public String next() { String r=line; line=readNextLine(); return r; }
        public void remove() { throw new UnsupportedOperationException(); }
    };
}
// 使用:for (String line : readLines("big.log")) System.out.println(line);

優勢:不載入全文到記憶體。缺點:Iterator 結束前無法關閉底層資源。

4. 可變對象作 HashMap Key 的災難

若 Key 的 hashCode() 依賴可變字段,修改字段後 map.get(key) 返回 null,因雜湊桶位置已變。

Person p = new Person("Ted", "Neward", 39);
map.put(p, "value");
p.setLastName("Finkelstein"); // hashCode 改變
map.get(p); // 返回 null!物件在錯誤桶中

鐵律:絕不使用可變對象作 HashMap Key。

5. Set 的相等性:equals() vs Comparable

TreeSet 使用 Comparator/Comparable 判斷相等(compareTo==0),而非 equals()。兩者語義不同:

  • 按姓氏排序時,不同人同姓 → compareTo==0 → 視為重複 → 僅保留一個
  • 但 equals() 可能返回 false(完整屬性不同)

實現 Comparable 時必須確保 compareTo==0 ⇔ equals(),否則 Set 行為違反直覺。

下期預告

Concurrent Collections(java.util.concurrent),JDK 5 引入的併發集合金礦。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved