java使用Stream流對(duì)自定義對(duì)象數(shù)組去重的實(shí)現(xiàn)
在 Java 中,使用 Stream 流對(duì)自定義對(duì)象數(shù)組去重的核心是確保對(duì)象能正確判斷“重復(fù)”的邏輯。以下是具體實(shí)現(xiàn)方法及場(chǎng)景分析:
方法 1:直接使用 distinct()(需重寫(xiě) equals 和 hashCode)
若自定義對(duì)象已正確重寫(xiě) equals() 和 hashCode() 方法,可直接通過(guò) distinct() 去重。
適用場(chǎng)景:對(duì)象的唯一性由所有字段共同決定(如數(shù)據(jù)庫(kù)實(shí)體類的主鍵)。
示例代碼
public class Person {
private String id;
private String name;
// 構(gòu)造方法、Getter/Setter 省略
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(id, person.id); // 根據(jù) id 判斷是否相等
}
@Override
public int hashCode() {
return Objects.hash(id); // 基于 id 生成哈希
}
}
// 使用 Stream 去重
Person[] people = ...; // 自定義對(duì)象數(shù)組
List<Person> uniqueList = Arrays.stream(people)
.distinct()
.collect(Collectors.toList());
方法 2:基于對(duì)象的某個(gè)唯一屬性去重(無(wú)需重寫(xiě) equals 和 hashCode)
若無(wú)法修改對(duì)象類(如第三方庫(kù)的類),或需根據(jù)部分字段去重,可用 Collectors.toMap 或 TreeSet 實(shí)現(xiàn)。
(1) 使用 Collectors.toMap
適用場(chǎng)景:根據(jù)唯一鍵(如 id)去重,保留第一個(gè)出現(xiàn)的元素。
List<Person> uniqueList = Arrays.stream(people)
.collect(Collectors.toMap(
Person::getId, // Key 提取函數(shù)(根據(jù) id 去重)
p -> p, // Value 為對(duì)象本身
(existing, replacement) -> existing // 沖突時(shí)保留已存在的元素
))
.values() // 獲取去重后的 Value 集合
.stream()
.collect(Collectors.toList());
(2) 使用 TreeSet 自定義比較器
適用場(chǎng)景:需要根據(jù)多個(gè)字段去重,或動(dòng)態(tài)指定去重規(guī)則。
List<Person> uniqueList = Arrays.stream(people)
.collect(Collectors.toCollection(
() -> new TreeSet<>(Comparator.comparing(p -> p.getId() + p.getName()))
))
.stream()
.collect(Collectors.toList());
方法 3:使用 filter + 內(nèi)存狀態(tài)去重
適用場(chǎng)景:需根據(jù)動(dòng)態(tài)條件去重(如去重后保留最后一個(gè)元素)。
(1) 使用 ConcurrentHashMap 維護(hù)狀態(tài)
Set<String> seenIds = ConcurrentHashMap.newKeySet();
List<Person> uniqueList = Arrays.stream(people)
.filter(p -> seenIds.add(p.getId())) // 若 id 未出現(xiàn)過(guò),保留
.collect(Collectors.toList());
(2) 保留最后一個(gè)出現(xiàn)的元素
List<Person> uniqueList = Arrays.stream(people)
.collect(Collectors.toMap(
Person::getId,
p -> p,
(oldValue, newValue) -> newValue // 沖突時(shí)保留新元素
))
.values()
.stream()
.collect(Collectors.toList());
總結(jié)回答
- 直接去重:若對(duì)象重寫(xiě)了
equals()和hashCode(),直接用distinct()。 - 按屬性去重:使用
Collectors.toMap或TreeSet,根據(jù)唯一鍵(如id)過(guò)濾。 - 動(dòng)態(tài)去重:通過(guò)
filter配合內(nèi)存集合(如ConcurrentHashMap)控制去重邏輯。
關(guān)鍵點(diǎn):明確業(yè)務(wù)中“重復(fù)”的定義(如全字段相等或部分字段相等),選擇性能與代碼簡(jiǎn)潔性兼顧的方案。
到此這篇關(guān)于java使用Stream流對(duì)自定義對(duì)象數(shù)組去重的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)java 自定義對(duì)象數(shù)組去重內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中使用@Async注解失效場(chǎng)景及說(shuō)明
在Spring?Boot中,@Async注解就像一把刀,能幫你輕松處理那些耗時(shí)的任務(wù),讓主線程可以繼續(xù)忙別的事兒,不過(guò),跟所有強(qiáng)大的工具一樣,用不好它也可能出岔子,為了避免這些坑,咱們得深入了解下@Async注解,接下來(lái),咱們就來(lái)聊聊7種常見(jiàn)的@Async失效情況,需要的朋友可以參考下2024-07-07
在Java中將double轉(zhuǎn)換為int的操作方法
這篇文章主要介紹了在Java中將double轉(zhuǎn)換為int的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
Java中l(wèi)ambda表達(dá)式的基本運(yùn)用
大家好,本篇文章主要講的是Java中l(wèi)ambda表達(dá)式的基本運(yùn)用,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01
Java用GDAL讀寫(xiě)shapefile的方法示例
Shapefile文件是描述空間數(shù)據(jù)的幾何和屬性特征的非拓?fù)鋵?shí)體矢量數(shù)據(jù)結(jié)構(gòu)的一種格式,由ESRI公司開(kāi)發(fā)。這篇文章給大家介紹了Java如何用GDAL讀寫(xiě)shapefile的方法示例,有需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。2016-12-12
JVM加載class文件的原理機(jī)制實(shí)例詳解
Java是一種具有動(dòng)態(tài)性的解釋型語(yǔ)言,類(class)只有被加載到JVM后才能運(yùn)行,接下來(lái)通過(guò)本文給大家介紹JVM加載class文件的原理機(jī)制詳解,感興趣的朋友一起看看吧2022-04-04
利用Java編寫(xiě)一個(gè)出敬業(yè)福的小程序
新年將至,又開(kāi)始掃?;顒?dòng),每年的敬業(yè)福成了大家難過(guò)的坎。所以本文將介紹一個(gè)通過(guò)Java編寫(xiě)的一款福字生成器,感興趣的小伙伴可以試一試2022-01-01

