Java 陣列長度固定,刪除元素或去重本質上是**建立新陣列**。本文提供多種實現方式,從基礎 List 轉換到 Java 8 Stream、工具庫,並分析效能差異。
public static String[] removeElement(String[] src, String target) {
if (src == null) return new String[0];
List<String> list = new ArrayList<>(Arrays.asList(src));
list.remove(target); // 移除第一個匹配項
// list.removeIf(s -> target.equals(s)); // 移除所有匹配項
return list.toArray(new String[0]);
}
public static String[] removeAt(String[] src, int index) {
if (src == null || index < 0 || index >= src.length) return src;
String[] dest = new String[src.length - 1];
System.arraycopy(src, 0, dest, 0, index);
System.arraycopy(src, index + 1, dest, index, src.length - index - 1);
return dest;
}
public static String[] distinct(String[] src) {
if (src == null) return new String[0];
return new LinkedHashSet<>(Arrays.asList(src)).toArray(new String[0]);
}
public static String[] distinctStream(String[] src) {
return Arrays.stream(src).distinct().toArray(String[]::new);
}
public static String[] distinctManual(String[] src) {
if (src == null) return new String[0];
List<String> result = new ArrayList<>();
for (String s : src) {
if (!result.contains(s)) result.add(s);
}
return result.toArray(new String[0]);
}
public class User {
private Long id;
private String name;
// getter/setter/equals/hashCode (基於 id)
}
public static <T> List<T> distinctByKey(List<T> list, Function<T, ?> keyExtractor) {
return list.stream()
.filter(new Predicate<T>() {
Set<Object> seen = new HashSet<>();
@Override public boolean test(T t) {
return seen.add(keyExtractor.apply(t));
}
})
.collect(Collectors.toList());
}
// 使用
List<User> unique = distinctByKey(users, User::getId);
public static int[] distinctInt(int[] src) {
return Arrays.stream(src).distinct().toArray();
}
// 或手動 (效能最優)
public static int[] distinctIntManual(int[] src) {
if (src == null) return new int[0];
Arrays.sort(src); // 排序使重複相鄰
int[] temp = new int[src.length];
int j = 0;
for (int i = 0; i < src.length; i++) {
if (i == 0 || src[i] != src[i-1]) {
temp[j++] = src[i];
}
}
return Arrays.copyOf(temp, j);
}
| 方法 | 時間複雜度 | 空間複雜度 | 順序保留 | 適用場景 |
|---|---|---|---|---|
| LinkedHashSet | O(n) | O(n) | ✅ | 通用物件、順序敏感 |
| Stream.distinct() | O(n) | O(n) | ✅ | 函數式風格、鏈式操作 |
| 排序+相鄰比較 | O(n log n) | O(1) 或 O(n) | ❌ (改變順序) | 基本型別、極大陣列、可接受重排 |
| 雙重循環 contains | O(n²) | O(n) | ✅ | 極小陣列 (<100)、教學 |
// Apache Commons Lang
ArrayUtils.removeElement(array, element);
ArrayUtils.remove(array, index);
// Guava
Arrays.asList(array).stream().distinct().toArray(String[]::new);
// 或
ImmutableSet.copyOf(array).asList().toArray(new String[0]);
equals()/hashCode(),或用 distinctByKey 指定業務鍵ArrayList 或 LinkedHashSet 作為主資料結構