// 通用去重:不保留順序
public static void removeDuplicates(Collection collection) {
Set set = new HashSet<>(collection);
collection.clear();
collection.addAll(set);
}
// 保留順序去重:LinkedHashSet
public static List distinctPreserveOrder(List list) {
return new ArrayList<>(new LinkedHashSet<>(list));
}
public class Person {
private int id;
private String name;
// 構造器、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 id == person.id && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name); // JDK 7+ 推薦
}
}
HashSet 去重原理:
hashCode() 確定桶位置equals() 比較契約:equals() 相等 ⇒ hashCode() 必相等;hashCode() 相等 ⇏ equals() 相等(哈希碰撞)。
// HashMap.putVal 核心判斷
if (e.hash == hash && (e.key == key || key.equals(e.key))) {
// 找到重複 key,替換 value
}
// HashSet.add 內部調用 map.put(e, PRESENT)
public boolean add(E e) {
return map.put(e, PRESENT) == null;
}
| 方法 | 耗時(ms) | 比較次數 | 複雜度 | 說明 |
|---|---|---|---|---|
| HashSet 去重 | 26 | 3,653 | O(n) | 哈希分桶,極少比較 |
| 雙重循環對比 | 378 | 28,463,252 | O(n²) | 全量遍歷比較,隨數據增長急劇惡化 |
// 低效寫法:O(n²)
public static void inefficientRemove(Person[] arr) {
Person[] result = new Person[arr.length];
int idx = 0;
for (int i = 0; i < arr.length; i++) {
boolean dup = false;
for (int j = 0; j < idx; j++) {
if (arr[i].equals(result[j])) { dup = true; break; }
}
if (!dup) result[idx++] = arr[i];
}
}
// 數組 → List(固定長度,不可增刪)
String[] arr = {"a", "b", "c"};
List list = Arrays.asList(arr); // 返回 Arrays$ArrayList,非 ArrayList
List mutableList = new ArrayList<>(Arrays.asList(arr)); // 可變副本
// List → 數組
List list = new ArrayList<>();
list.add("x");
String[] toArray = list.toArray(new String[0]); // JDK 11+ 推薦 new String[0]
// 基本類型數組無法直接轉 List,需流式處理
int[] ints = {1,2,3};
List intList = Arrays.stream(ints).boxed().collect(Collectors.toList());
list.stream().collect(Collectors.toMap(Person::getId, p -> p, (a,b) -> a)).values()ConcurrentHashMap.newKeySet() 或 Collections.synchronizedSetTreeSet<>(Comparator.comparing(Person::getId)) 保序去重