Java 數組長度固定,無法真正刪除元素。所謂「刪除」實際是:創建新數組,複製保留元素,或將後續元素前移覆蓋目標位置。
public static String[] removeByNewArray(String[] src, String target) {
if (src == null) return new String[0];
// 先計算保留數量
int count = 0;
for (String s : src) {
if (!target.equals(s)) count++;
}
String[] result = new String[count];
int idx = 0;
for (String s : src) {
if (!target.equals(s)) {
result[idx++] = s;
}
}
return result;
}
public static int removeInPlace(String[] arr, String target) {
if (arr == null) return 0;
int writeIdx = 0;
for (int readIdx = 0; readIdx < arr.length; readIdx++) {
if (!target.equals(arr[readIdx])) {
arr[writeIdx++] = arr[readIdx];
}
}
// 清理尾部殘留引用(助 GC)
Arrays.fill(arr, writeIdx, arr.length, null);
return writeIdx; // 返回新有效長度
}
public static String[] removeByList(String[] src, String target) {
if (src == null) return new String[0];
return Arrays.stream(src)
.filter(s -> !target.equals(s))
.toArray(String[]::new);
}
// 或經典寫法:
// List list = new ArrayList<>(Arrays.asList(src));
// list.removeIf(target::equals);
// return list.toArray(new String[0]);
| 場景 | 新數組 | arraycopy | Stream/List |
|---|---|---|---|
| 1萬元素,刪除10% | ~0.3ms | ~0.15ms ⭐ | ~0.5ms |
| 100萬元素,刪除50% | ~25ms | ~12ms ⭐ | ~40ms |
System.arraycopy 是 JVM 內部優化的本地方法,大量數據移動時性能碾壓其他方式。
System.arraycopy 原地前移,返回新長度List.removeIf() 或 Stream API,可讀性最高CopyOnWriteArrayList 或加鎖Arrays.asList(arr).remove(target) → 拋出 UnsupportedOperationException(返回固定長度 List)arr[i] = null 不移動後續元素 → 留下「空洞」,遍歷報 NPEArrays.fill(arr, newLen, arr.length, null) 清理尾部引用,防止內存洩漏// Java 8+ 最優雅寫法
String[] result = Arrays.stream(arr).filter(s -> !target.equals(s)).toArray(String[]::new);
理解數組固定長度的本質,選擇合適工具,才能寫出又快又穩的代碼。