首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 數組元素刪除並前移的高效實現方式

     編輯:Java 相關知識

問題本質

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;
}

方式二:System.arraycopy 前移覆蓋(原地操作,性能最優)

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; // 返回新有效長度
}

方式三:List 集合轉換(代碼最簡潔,開銷稍大)

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]);

性能基準測試(JMH 大致數據)

場景新數組arraycopyStream/List
1萬元素,刪除10%~0.3ms~0.15ms ⭐~0.5ms
100萬元素,刪除50%~25ms~12ms ⭐~40ms

System.arraycopy 是 JVM 內部優化的本地方法,大量數據移動時性能碾壓其他方式。

最佳實踐建議

  1. 高頻/大數據量:優先用 System.arraycopy 原地前移,返回新長度
  2. 業務代碼/小數據:用 List.removeIf() 或 Stream API,可讀性最高
  3. 需要頻繁增刪:直接用 ArrayList,別死磕數組
  4. 多線程環境:考慮 CopyOnWriteArrayList 或加鎖

陷阱提醒

  • ❌ Arrays.asList(arr).remove(target) → 拋出 UnsupportedOperationException(返回固定長度 List)
  • ❌ 直接 arr[i] = null 不移動後續元素 → 留下「空洞」,遍歷報 NPE
  • ✅ 刪除後務必 Arrays.fill(arr, newLen, arr.length, null) 清理尾部引用,防止內存洩漏

一行代碼總結

// Java 8+ 最優雅寫法
String[] result = Arrays.stream(arr).filter(s -> !target.equals(s)).toArray(String[]::new);

理解數組固定長度的本質,選擇合適工具,才能寫出又快又穩的代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved