Hashtable(或現代 HashMap/HashSet)鍵值唯一特性,天然適合字符串集合的去重、差集、過濾操作。本文提供三個現成工具方法,並說明順序不穩定問題及改進方向。
public String[] distinct(String[] arr) {
Hashtable ht = new Hashtable<>();
for (String s : arr) if (!ht.containsKey(s)) ht.put(s, s);
String[] res = new String[ht.size()];
int i = 0;
for (Enumeration e = ht.keys(); e.hasMoreElements(); ) res[i++] = e.nextElement();
return res;
}
// 測試
String[] mobile = {"13811071500","13811071500","13811071501","13811071503","13811071501"};
// 輸出順序不固定:13811071503, 13811071501, 13811071500
public String[] difference(String[] a, String[] b) {
Hashtable setB = new Hashtable<>();
for (String s : b) setB.put(s, s);
Hashtable diff = new Hashtable<>();
for (String s : a) if (!setB.containsKey(s)) diff.put(s, s);
String[] res = new String[diff.size()];
int i = 0;
for (Enumeration e = diff.keys(); e.hasMoreElements(); ) res[i++] = e.nextElement();
return res;
}
// 測試
String[] m1 = {"13811071500","13811071501","13811071502","13811071503","13811071504"};
String[] m2 = {"13811071500","13811071505","13811071502","13811071506","13811071504"};
// 輸出:13811071503, 13811071501
public String[] remove(String[] arr, String target) {
Hashtable ht = new Hashtable<>();
for (String s : arr) if (!s.equals(target)) ht.put(s, s);
String[] res = new String[ht.size()];
int i = 0;
for (Enumeration e = ht.keys(); e.hasMoreElements(); ) res[i++] = e.nextElement();
return res;
}
| 問題 | 原因 | 改進建議 |
|---|---|---|
| 輸出順序與輸入不一致 | Hashtable/HashMap 無序 | 改用 LinkedHashSet 保持插入順序 |
| 線程安全開銷 | Hashtable 所有方法同步 | 單線程環境用 HashMap/HashSet;多線程用 ConcurrentHashMap |
| 泛型擦除警告 | 舊式 Enumeration 遍歷 | 用 for (String k : set.keySet()) 或 Stream API |
import java.util.*;
import java.util.stream.Collectors;
public class StringArrayUtils {
public static String[] distinct(String[] arr) {
return Arrays.stream(arr).distinct().toArray(String[]::new);
}
public static String[] difference(String[] a, String[] b) {
Set setB = new HashSet<>(Arrays.asList(b));
return Arrays.stream(a).filter(s -> !setB.contains(s)).distinct().toArray(String[]::new);
}
public static String[] remove(String[] arr, String target) {
return Arrays.stream(arr).filter(s -> !s.equals(target)).distinct().toArray(String[]::new);
}
}
Hashtable 解決字符串集合運算簡潔有效,但生產代碼建議升級為 LinkedHashSet + Stream API,兼顧順序、效能與可讀性。