Java中List數(shù)據(jù)去重的3種有效方法總結(jié)
前言
在日常 Java 開發(fā)中,List 集合去重是一個非常常見的需求。根據(jù) 是否需要保持順序、數(shù)據(jù)規(guī)模大小、JDK 版本 的不同,去重方式也有所區(qū)別。
本文總結(jié)了 5 種常見且實用的 List 去重方法,并對每種方法的使用場景、優(yōu)缺點進(jìn)行了說明,供大家在實際項目中選擇合適的方案。
一、使用 Java 8 Stream 的distinct()方法(推薦)
適用場景:
JDK 8 及以上
追求代碼簡潔、可讀性強(qiáng)
示例代碼
public static List<String> delRepeat(List<String> list) {
return list.stream()
.distinct()
.collect(Collectors.toList());
}
原理說明
distinct()底層依賴對象的equals()和hashCode()方法會自動過濾掉重復(fù)元素
保留原 List 中的順序
優(yōu)缺點
優(yōu)點:
代碼簡潔、優(yōu)雅
可讀性強(qiáng)
保留原順序
缺點:
僅適用于 JDK 8 及以上
二、借助 Set 的特性進(jìn)行去重(List 與 Set 轉(zhuǎn)換)
適用場景:
不關(guān)心元素順序
對性能有一定要求
示例代碼
/**
* 去除重復(fù)數(shù)據(jù)
* 注意:Set 是無序的,不會保持原有順序
*/
public static List<String> listDistinct(List<String> list) {
List<String> result = new ArrayList<>();
if (list != null && !list.isEmpty()) {
Set<String> set = new HashSet<>(list);
result.addAll(set);
}
return result;
}
原理說明
HashSet天生不允許重復(fù)元素通過 Set 進(jìn)行一次“過濾”
優(yōu)缺點
優(yōu)點:
性能較好
實現(xiàn)簡單
缺點:
無法保證原 List 的順序
三、遍歷 List,將元素添加到另一個 List 中(保持順序)
適用場景:
數(shù)據(jù)量較小
需要嚴(yán)格保持原有順序
示例代碼
public static List<String> delRepeat(List<String> list) {
List<String> listNew = new ArrayList<>();
for (String str : list) {
if (!listNew.contains(str)) {
listNew.add(str);
}
}
return listNew;
}
原理說明
利用
List.contains()判斷是否已存在不存在則加入新 List
優(yōu)缺點
優(yōu)點:
思路直觀
順序完全一致
缺點:
時間復(fù)雜度較高(O(n²))
不適合大數(shù)據(jù)量
四、利用 Set 去重并保持原有順序(強(qiáng)烈推薦)
如果既想去重,又想保持順序,這是非常實用的一種方式。
方法一:使用TreeSet(會排序)
List<String> listNew = new ArrayList<>(new TreeSet<>(list));
注意:
TreeSet會自動排序如果不希望順序被改變,請慎用
方法二:使用LinkedHashSet(推薦)
List<String> listNew = new ArrayList<>(new LinkedHashSet<>(list));
原理說明
LinkedHashSet內(nèi)部維護(hù)了插入順序去重的同時保持 List 原有順序
優(yōu)缺點
優(yōu)點:
性能好
順序穩(wěn)定
代碼簡潔
缺點:
需要額外的 Set 容器
實際開發(fā)中非常推薦這一種方式
五、使用 List 的remove()方法去重(不推薦 )
適用場景:
幾乎不推薦,僅用于理解原理
示例代碼
/**
* 去除重復(fù)數(shù)據(jù)(一般不推薦)
* 類似于冒泡排序思想
*/
public static List<Map<String, Object>> distinct(List<Map<String, Object>> list) {
if (list != null && list.size() > 0) {
for (int i = 0; i < list.size() - 1; i++) {
for (int j = list.size() - 1; j > i; j--) {
// 根據(jù)實際業(yè)務(wù)修改比較規(guī)則
if (list.get(j).equals(list.get(i))) {
list.remove(j);
}
}
}
}
return list;
}
缺點
- 時間復(fù)雜度高(O(n²))
- 直接修改原 List,風(fēng)險較大
- 可讀性和維護(hù)性較差
總結(jié)對比
| 方法 | 是否推薦 | 是否保持順序 | 適用場景 |
|---|---|---|---|
| Stream distinct | ????? | 是 | JDK 8+,代碼簡潔 |
| HashSet 轉(zhuǎn)換 | ??? | 否 | 不關(guān)心順序 |
| 遍歷 List | ?? | 是 | 小數(shù)據(jù)量 |
| LinkedHashSet | ????? | 是 | 最常用、最穩(wěn)妥 |
| remove() 去重 | ? | 是 | 不推薦 |
到此這篇關(guān)于Java中List數(shù)據(jù)去重的3種有效方法的文章就介紹到這了,更多相關(guān)Java List數(shù)據(jù)去重內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA?JNA調(diào)用C接口的三種實現(xiàn)方式
文章主要介紹了使用JNA(Java?Native?Access)調(diào)用C庫的方法,包括繼承Library接口、直接使用`NativeLibrary`實例和使用頭文件實現(xiàn)接口等方式,并詳細(xì)描述了在Linux環(huán)境下使用JNA調(diào)用C庫的具體操作步驟,還涉及到了一些遇到的問題的解決方法2026-05-05
SpringBoot中@Conditional注解的介紹及實踐
在 Spring Boot 中,@Conditional 注解用于實現(xiàn) 條件化 Bean 裝配,本文將詳細(xì)介紹 @Conditional 相關(guān)的注解,并結(jié)合實際應(yīng)用示例講解其使用方式,感興趣的小伙伴可以了解下2025-03-03
Springboot如何統(tǒng)一處理Filter異常
這篇文章主要介紹了Springboot如何統(tǒng)一處理Filter異常問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
SpringBoot項目中使用騰訊云發(fā)送短信的實現(xiàn)
本文主要介紹了SpringBoot項目中使用騰訊云發(fā)送短信的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04

