集合類型轉換是資料處理管道的基礎操作。本文對比 Apache Commons Collections、Java 8 Stream API、核心 JDK 三種方案,給出各場景最佳選擇與效能參考。
| 轉換方向 | 核心 JDK | Commons Collections | Stream API (Java 8+) |
|---|---|---|---|
| 陣列 → List | `Arrays.asList(arr)` (固定長) `new ArrayList<>(Arrays.asList(arr))` | `CollectionUtils.addAll(list, arr)` | `Arrays.stream(arr).collect(toList())` |
| List → 陣列 | `list.toArray(new T[0])` | 無專用 | `list.toArray(T[]::new)` |
| List → Set | `new HashSet<>(list)` | `new HashSet<>(list)` | `list.stream().collect(toSet())` |
| Set → List | `new ArrayList<>(set)` | `new ArrayList<>(set)` | `set.stream().collect(toList())` |
| 陣列 → Set | `new HashSet<>(Arrays.asList(arr))` | `CollectionUtils.addAll(set, arr)` | `Arrays.stream(arr).collect(toSet())` |
| Map → Collection | `map.values()` | `MapUtils.values(map)` | `map.values().stream().collect(toList())` |
String[] arr = {"a", "b", "c"};
// 只讀視圖
List<String> fixed = Arrays.asList(arr);
// 可變獨立副本
List<String> mutable = new ArrayList<>(Arrays.asList(arr));
// Java 9+ 不可變
List<String> immutable = List.of(arr);
String[] arr = list.toArray(new String[0]); // 零長度陣列,JDK 11+ 零拷貝優化
// List 去重保留順序 → LinkedHashSet
Set<String> unique = new LinkedHashSet<>(list);
List<String> deduped = new ArrayList<>(unique);
// 陣列 → List 並過濾空值
List<String> filtered = Arrays.stream(arr)
.filter(Objects::nonNull)
.map(String::trim)
.filter(s -> !s.isEmpty())
.collect(toList());
// List → Map (分組/索引)
Map<Long, User> idMap = users.stream()
.collect(toMap(User::getId, u -> u, (a, b) -> a)); // 鍵衝突策略
// 僅在無法升級 JDK 5/6 專案使用
CollectionUtils.addAll(list, arr); // 內部仍是迴圈 add,無額外優勢
// 提供額外工具:CollectionUtils.union/intersection/disjunction
| 操作 | 核心 JDK (ms) | Stream (ms) | 備註 |
|---|---|---|---|
| 陣列 → ArrayList | 14 | 38 | Stream 額外 Lambda 開銷 |
| List → 陣列 | 11 | 13 | 接近 |
| List → HashSet (去重) | 45 | 52 | 雜湊計算主導 |
| Stream 並行去重 | -- | 28 | 多核加速明顯 |
掌握三大方案優勢與適用邊界,能在重構舊代碼、編寫高效能管道、適配不同 JDK 版本時遊刃有餘。