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

Java 陣列刪除元素與去重完整代碼範例

     編輯:Java 相關知識

前言

Java 陣列長度固定,刪除元素或去重本質上是**建立新陣列**。本文提供多種實現方式,從基礎 List 轉換到 Java 8 Stream、工具庫,並分析效能差異。

1. 刪除指定元素 (基於 List)

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

2. 刪除指定索引

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

3. 陣列去重 (保留順序)

方案 A:LinkedHashSet (最簡潔、O(n))

public static String[] distinct(String[] src) {
    if (src == null) return new String[0];
    return new LinkedHashSet<>(Arrays.asList(src)).toArray(new String[0]);
}

方案 B:Java 8 Stream (函數式)

public static String[] distinctStream(String[] src) {
    return Arrays.stream(src).distinct().toArray(String[]::new);
}

方案 C:手動雙重循環 (教學用、O(n²))

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

4. 進階:自定義對象去重 (需實作 equals/hashCode)

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

5. 基本型別陣列去重 (int[] 等)

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

效能對比 (百萬級資料)

方法時間複雜度空間複雜度順序保留適用場景
LinkedHashSetO(n)O(n)✅通用物件、順序敏感
Stream.distinct()O(n)O(n)✅函數式風格、鏈式操作
排序+相鄰比較O(n log n)O(1) 或 O(n)❌ (改變順序)基本型別、極大陣列、可接受重排
雙重循環 containsO(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]);

總結

  1. **陣列不可變**,刪除/去重 = 建立新陣列
  2. **首選 LinkedHashSet / Stream.distinct()**:代碼簡潔、O(n)、保留順序
  3. **基本型別大陣列**考慮排序+相鄰比較 (O(n log n) 但空間 O(1))
  4. **自定義對象**務必正確實作 equals()/hashCode(),或用 distinctByKey 指定業務鍵
  5. 高頻操作考慮改用 ArrayList 或 LinkedHashSet 作為主資料結構
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved