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

Java List 去重複元素的三種高效寫法 (ArrayList 實戰)

     編輯:Java 相關知識

針對 ArrayList 移除重複元素,提供三種不同效能與適用場景的寫法,並說明底層原理與選型建議。

測試資料

List<String> list = Arrays.asList(
    "java03", "java03", "java01", "java02", "java01", "java02", "java01"
);
// 預期結果:[java03, java01, java02] (保留首次出現順序)

寫法 1:迭代器 + 新 List (保留順序、JDK 1.2+ 通用)

public static <T> List<T> distinctWithIterator(List<T> src) {
    List<T> result = new ArrayList<>();
    for (Iterator<T> it = src.iterator(); it.hasNext(); ) {
        T elem = it.next();
        if (!result.contains(elem)) result.add(elem); // O(n) 查找
    }
    return result;
}
// 時間複雜度:O(n²) — 適合小資料量 ( < 1000 )

寫法 2:LinkedHashSet (保留順序、O(n) 期望時間、JDK 1.4+)

public static <T> List<T> distinctWithLinkedHashSet(List<T> src) {
    return new ArrayList<>(new LinkedHashSet<>(src));
}
// LinkedHashSet 內部雜湊表 + 雙向鏈表,同時保證唯一性與插入順序
// 時間複雜度:O(n) — **通用首選**

寫法 3:Stream API (JDK 8+、函數風格、可並行)

public static <T> List<T> distinctWithStream(List<T> src) {
    return src.stream().distinct().collect(Collectors.toList());
}
// 底層同 LinkedHashSet,語意更清晰,支援 parallelStream() 大資料並行去重

效能對比 (10 萬筆隨機字串)

Iterator+List      : ~1,200 ms  (O(n²) 明顯劣勢)
LinkedHashSet      : ~15 ms
Stream.distinct()  : ~18 ms

進階場景:依據物件特定欄位去重

// 例:User 物件以 id 去重
List<User> users = ...;
List<User> unique = users.stream()
    .collect(Collectors.collectingAndThen(
        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getId))),
        ArrayList::new
    ));
// 或使用 Map 去重 (保留首次/最後出現)
Map<Long, User> map = users.stream()
    .collect(Collectors.toMap(User::getId, u -> u, (v1, v2) -> v1)); // 保留首次
List<User> unique2 = new ArrayList<>(map.values());

選型決策表

場景推薦寫法理由
一般業務 List 去重 (保留順序)new ArrayList<>(new LinkedHashSet<>(list))簡潔、O(n)、無額外依賴
JDK 8+ 專案、偏好函數風格list.stream().distinct().collect(toList())語意明確、易並行化
極小資料量 (<100)、避免建立額外集合迭代器手寫零額外物件分配
依據特定屬性去重Stream + toMap / TreeSet + Comparator靈活控制比較邏輯
高併發環境、共享 ListCopyOnWriteArrayList + 上述任一執行緒安全快照

原始碼範例 (對應文章提供的寫法 1)

import java.util.*;

class ArrayListDistinct {
    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<>(Arrays.asList(
            "java03", "java03", "java01", "java02", "java01", "java02", "java01"
        ));
        System.out.println("去重前: " + al);

        ArrayList<String> result = distinct(al);
        System.out.println("去重後: " + result);
    }

    static ArrayList<String> distinct(ArrayList<String> src) {
        ArrayList<String> newAl = new ArrayList<>();
        Iterator<String> it = src.iterator();
        while (it.hasNext()) {
            String obj = it.next();
            if (!newAl.contains(obj)) newAl.add(obj);
        }
        return newAl;
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved