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

Java 獲取兩個數組差集 (差異元素) 的高效方法

     編輯:Java 相關知識

需求

給定兩個數組 arr1, arr2,求 **在 arr2 中但不在 arr1 中的元素** (即 arr2 - arr1 差集)。保留 arr2 的順序與重複性 (視業務而定)。

方法一:List + contains (簡單、O(n*m))

public static  List diffList(T[] arr1, T[] arr2) {
    List list1 = Arrays.asList(arr1); // O(1) 轉換,底層數組
    List diff = new ArrayList<>();
    for (T t : arr2) {
        if (!list1.contains(t)) diff.add(t); // contains 為 O(n) 線性查找
    }
    return diff;
}
// 測試
diffList(new Integer[]{1,2,3}, new Integer[]{1,2,3,4}); // [4]

缺點:大數組時性能差,contains 走 equals 比較。

方法二:HashSet 查找 (推薦、O(n+m))

public static  List diffSet(T[] arr1, T[] arr2) {
    Set set1 = new HashSet<>(Arrays.asList(arr1)); // O(n) 建立
    List diff = new ArrayList<>();
    for (T t : arr2) {
        if (!set1.contains(t)) diff.add(t); // O(1) 查找
    }
    return diff;
}

優點:時間複雜度線性,適合萬級以上數據。
注意:要求元素正確實現 hashCode()/equals()。

方法三:Stream API (Java 8+、函數式風格)

public static  List diffStream(T[] arr1, T[] arr2) {
    Set set1 = new HashSet<>(Arrays.asList(arr1));
    return Arrays.stream(arr2)
                 .filter(t -> !set1.contains(t))
                 .collect(Collectors.toList());
}

方法四:基本類型數組優化 (避免裝箱)

public static int[] diffPrimitive(int[] arr1, int[] arr2) {
    // 使用 IntSet (如 fastutil) 或排序雙指針
    Arrays.sort(arr1); // O(n log n)
    List diff = new ArrayList<>();
    for (int v : arr2) {
        if (Arrays.binarySearch(arr1, v) < 0) diff.add(v); // O(log n)
    }
    return diff.stream().mapToInt(i -> i).toArray();
}

去重與順序選項

性能基準 (10 萬元素)

// List+contains : ~1200 ms
// HashSet       : ~15 ms
// Stream+HashSet: ~18 ms
// 排序+二分     : ~30 ms

總結

**首選 HashSet + 循環/Stream**,代碼簡潔、性能優異、語義清晰。基本類型大數組可考慮排序+二分或專用庫 (fastutil, Eclipse Collections)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
需求實現
保留 arr2 順序、保留重複上述所有方法默認行為
保留順序、去重加 LinkedHashSet 過濾 diff
不保留順序、去重直接 set2.removeAll(set1)