Java集合框架(JCF)以Collection<E>為根接口,統一了「對象組」的操作契約。所有集合實現類(直接或間接)實現此接口,並繼承Iterable<E>,賦予統一遍歷能力。本文深度剖析Collection接口契約、Iterator設計精髓、實現類構造約定及equals/hashCode語義。
public interface Collection<E> extends Iterable<E> {
// 查詢操作
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator<E> iterator();
Object[] toArray();
<T> T[] toArray(T[] a);
// 修改操作(可選,不可修改集合拋UnsupportedOperationException)
boolean add(E e);
boolean remove(Object o);
// 批量操作
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c);
void clear();
// 比較與哈希
boolean equals(Object o);
int hashCode();
// 流式操作(Java 8+)
default Stream<E> stream() { ... }
default Stream<E> parallelStream() { ... }
}
Collection(Collection<? extends E> c) → 複製構造器,創建等效集合Collections.unmodifiableList),必須拋UnsupportedOperationExceptionnull、類型,違規拋NullPointerException/ClassCastExceptioncontains(o)語義為o==null ? e==null : o.equals(e)。實現可優化(先比hashCode),但不可違背語義
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() { throw new UnsupportedOperationException(); }
default void forEachRemaining(Consumer<? super E> action) { ... }
}
remove()在遍歷中刪除最近返回的元素,避免ConcurrentModificationExceptionhasNext/next替代hasMoreElements/nextElement,更簡潔專為List設計,雙向遍歷(hasPrevious/previous)、索引獲取(nextIndex/previousIndex)、插入(add)、修改(set),是List專屬的強力游標。
Collection
├── List // 有序、可重複、索引訪問
│ ├── ArrayList
│ ├── LinkedList
│ └── Vector (legacy)
├── Set // 無序、唯一
│ ├── HashSet
│ ├── LinkedHashSet
│ └── TreeSet (SortedSet)
└── Queue // 佇列語義
├── PriorityQueue
├── ArrayDeque (Deque)
└── LinkedList (Deque)
注意:Map不繼承Collection,但提供values()(Collection)、keySet()(Set)、entrySet()(Set<Map.Entry>)橋接。
// 良好實現:複製構造器保持類型特性
public class MyArrayList<E> extends ArrayList<E> {
public MyArrayList() { super(); }
public MyArrayList(Collection<? extends E> c) { super(c); } // 關鍵!
public MyArrayList(int capacity) { super(capacity); }
}
// 使用:類型安全複製
List<String> src = new MyArrayList<>(List.of("a", "b"));
List<String> copy = new ArrayList<>(src); // 類型擦除後仍安全
| 場景 | 問題 | 解決方案 |
|---|---|---|
| 單線程遍歷中修改 | fail-fast → ConcurrentModificationException | 用Iterator.remove()或收集待刪元素後批量刪除 |
| 多線程並發遍歷 | 數據競爭、拋異常、死循環 | ① CopyOnWriteArrayList(讀多寫少)② ConcurrentHashMap鍵值視圖(弱一致性迭代器)③ 加鎖遍歷(性能差) ④ 並行流 parallelStream()(無副作用操作) |
// 集合 → Stream → 聚合/轉換 → 收集回集合
List<String> result = collection.stream()
.filter(s -> s.length() > 3)
.map(String::toUpperCase)
.distinct()
.sorted()
.collect(Collectors.toList()); // 或 toSet(), toCollection(TreeSet::new)
stream()默認串行、parallelStream()並行(ForkJoinPool.commonPool())。注意:流操作不修改源集合,無副作用函數式風格。
Collection與Iterator構成JCF的「雙子星」:前者定義容器契約,後者提供統一遍歷抽象。掌握其語義規範(構造器、equals、可選操作、fail-fast)、子接口分工、併發遍歷策略、流式轉換模式,是寫出正確、高效、可維護集合代碼的前提。下一步建議深入List/Set/Queue子接口契約、Map體系、併發集合、Stream API進階。