java使用 ?Stream 流對自定義對象數組去重的

在 Java 中,使用 Stream 流對自定義對象數組去重的核心是確保對象能正確判斷“重復”的邏輯。以下是具體實現方法及場景分析:


方法 1:直接使用 distinct()(需重寫 equalshashCode

若自定義對象已正確重寫 equals()hashCode() 方法,可直接通過 distinct() 去重。
適用場景:對象的唯一性由所有字段共同決定(如數據庫實體類的主鍵)。

示例代碼
public class Person {private String id;private String name;// 構造方法、Getter/Setter 省略@Overridepublic 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); // 根據 id 判斷是否相等}@Overridepublic int hashCode() {return Objects.hash(id); // 基于 id 生成哈希}
}// 使用 Stream 去重
Person[] people = ...; // 自定義對象數組
List<Person> uniqueList = Arrays.stream(people).distinct().collect(Collectors.toList());

方法 2:基于對象的某個唯一屬性去重(無需重寫 equalshashCode

若無法修改對象類(如第三方庫的類),或需根據部分字段去重,可用 Collectors.toMapTreeSet 實現。

(1) 使用 Collectors.toMap

適用場景:根據唯一鍵(如 id)去重,保留第一個出現的元素。

List<Person> uniqueList = Arrays.stream(people).collect(Collectors.toMap(Person::getId, // Key 提取函數(根據 id 去重)p -> p,       // Value 為對象本身(existing, replacement) -> existing // 沖突時保留已存在的元素)).values()            // 獲取去重后的 Value 集合.stream().collect(Collectors.toList());
(2) 使用 TreeSet 自定義比較器

適用場景:需要根據多個字段去重,或動態指定去重規則。

List<Person> uniqueList = Arrays.stream(people).collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(p -> p.getId() + p.getName())))).stream().collect(Collectors.toList());

方法 3:使用 filter + 內存狀態去重

適用場景:需根據動態條件去重(如去重后保留最后一個元素)。

(1) 使用 ConcurrentHashMap 維護狀態
Set<String> seenIds = ConcurrentHashMap.newKeySet();
List<Person> uniqueList = Arrays.stream(people).filter(p -> seenIds.add(p.getId())) // 若 id 未出現過,保留.collect(Collectors.toList());
(2) 保留最后一個出現的元素
List<Person> uniqueList = Arrays.stream(people).collect(Collectors.toMap(Person::getId,p -> p,(oldValue, newValue) -> newValue // 沖突時保留新元素)).values().stream().collect(Collectors.toList());

總結回答

  • 直接去重:若對象重寫了 equals()hashCode(),直接用 distinct()
  • 按屬性去重:使用 Collectors.toMapTreeSet,根據唯一鍵(如 id)過濾。
  • 動態去重:通過 filter 配合內存集合(如 ConcurrentHashMap)控制去重邏輯。

關鍵點:明確業務中“重復”的定義(如全字段相等或部分字段相等),選擇性能與代碼簡潔性兼顧的方案。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75902.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75902.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75902.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++ (類的設計,對象的創建,this指針,構造函數)

類的設計 C對結構體是有增強的 可以包含函數作為結構體成員 可以直接定義變量 在結構體成員函數里面可以直接訪問結構體成員變量 struct student{string name;int age;float score;void play_game(const string &name);}void student::play_game(const string game){}…

《ADVANCING MATHEMATICAL REASONING IN LAN- GUAGE MODELS》全文閱讀

《ADVANCING MATHEMATICAL REASONING IN LAN- GUAGE MODELS: THE IMPACT OF PROBLEM-SOLVING DATA, DATA SYNTHESIS METHODS, AND TRAINING STAGES》全文閱讀 提升語言模型中的數學推理能力&#xff1a;問題求解數據、數據合成方法及訓練階段的影響 \begin{abstract} 數學推…

網絡測試工具:涵蓋網絡測速、密碼查看、故障判斷與網絡監測

在網絡管理與維護的廣闊領域中&#xff0c;網絡測試工具扮演著至關重要的角色。它們不僅簡化了復雜的網絡診斷流程&#xff0c;還提升了工作效率。今天推薦一款包含功能全面的網絡測試工具&#xff1a;InetTest&#xff0c;是一款免費且開源的網絡測試工具&#xff0c;適用于Wi…

小剛說C語言刷題——1005 - 已知一個圓的半徑,求解該圓的面積和周長

1.題目描述 已知一個圓的半徑&#xff0c;求解該圓的面積和周長。 輸入 輸入只有一行&#xff0c;只有 1個整數。 輸出 輸出只有兩行&#xff0c;一行面積&#xff0c;一行周長。&#xff08;保留兩位小數&#xff09;。 令 pi3.1415926。 樣例 輸入 1 輸出 3.14 6.…

【算法】快速排序

算法系列六&#xff1a;快速排序 一、快速排序的遞歸探尋 1.思路 2.書寫 3.搭建 3.1設計過掉不符情況&#xff08;在最底層時&#xff09; 3.2查驗能實現基礎結果&#xff08;在最底層往上點時&#xff09; 3.3跳轉結果繼續往上回搭 4.實質 二、快速排序里的基準排序 …

SoapUI 4.6.4(32位)下載安裝教程 - 兼容老舊Windows系統

SoapUI 4.6.4&#xff08;32位版&#xff09; 是個老版本的測試工具&#xff0c;專門給 32位 Windows 電腦 用的。現在最新版都是 64 位的了&#xff0c;但如果你還在用老系統&#xff0c;可能還得找這個舊版。 SoapUI 4.6.4工具下載:https://pan.quark.cn/s/c07381db8102 這…

【AI量化第24篇】KhQuant 策略框架深度解析:讓策略開發回歸本質——基于miniQMT的量化交易回測系統開發實記

我是Mr.看海&#xff0c;我在嘗試用信號處理的知識積累和思考方式做量化交易&#xff0c;應用深度學習和AI實現股票自動交易&#xff0c;目的是實現財務自由~ 目前我正在開發基于miniQMT的量化交易系統——看海量化交易系統。 本篇要講到量化的核心了——策略。說白了每個投資者…

Java面試黃金寶典48

1. C++ 的拷貝構造函數,深拷貝和淺拷貝 定義 拷貝構造函數:在 C++ 里,拷貝構造函數屬于特殊的構造函數,其功能是使用一個已存在的對象來初始化一個新對象。當對象以值傳遞的方式作為參數傳給函數、函數返回對象、用一個對象初始化另一個對象時,拷貝構造函數會被調用。淺拷…

OpenCV學習之獲取圖像所有點的坐標位置(二)

1.功能介紹 (1)使用openCV解析了.jpeg、.jpg、.png格式的圖像文件,輸出了圖像的寬、高、通道數; (2)創建txt格式文件,保存圖像中各像素點的rgba值。 2.環境介紹 操作系統:window10 開發語言:visual studio 2015 c++ 3.功能實現過程 3.1環境設置 (1)打開Vs2015…

B2B2C多用戶商城平臺 的兩種創新玩法

以前隨便搞個淘寶京東那樣的商城就能躺著賺錢的日子早過去了&#xff01;現在市面上各種電商玩法花樣百出&#xff1a;小紅書那種刷著刷著就下單的"種草"電商&#xff0c;拼多多那種"幫我砍一刀"的社交電商&#xff0c;還有抖音快手那種看著視頻突然就想買…

【Bluedroid】A2DP Sink播放流程源碼分析(二)

接上一篇繼續分析&#xff1a;【Bluedroid】A2DP Sink播放流程源碼分析(一)_安卓a2dp sink播放流程-CSDN博客 AVDTP接收端&#xff08;Sink&#xff09;流事件處理 bta_av_sink_data_cback 是 Bluedroid 中 A2DP Sink 角色的 AVDTP 數據回調函數&#xff0c;負責處理接收端的…

抗量子算法驗證工具

抗量子算法計算工具 抗量子算法驗證工具ML-KEMML-DSASLH-DSA 抗量子算法驗證工具 2024年末&#xff0c;美國NIST陸續公布了FIPS-203、FIPS-204、FIPS-205算法標準文檔&#xff0c;抽空學習了一下&#xff0c;做了個算法計算工具。 ML-KEM ML-DSA SLH-DSA 需要的朋友可留言交流…

2025年PMP考試有哪些變化?難點在哪里?

PMP&#xff08;項目管理專業人士資格認證&#xff09;考試因其廣泛的行業認可度和實用性&#xff0c;成為許多專業人士提升職業競爭力的重要選擇。然而&#xff0c;對于初次接觸PMP考試的考生來說&#xff0c;其廣度與深度的平衡、理論與實踐的結合&#xff0c;以及跨文化思維…

Docker學習筆記-docker安裝、刪除

一、在centOS 7中docker的默認安裝目錄 # Docker 主配置文件目錄 ls /etc/docker# Docker 數據目錄&#xff08;鏡像、容器、卷等&#xff09; ls /var/lib/docker# Docker 可執行文件路徑 which docker # 輸出類似 /usr/bin/docker 二、docker文件目錄說明 目錄/文件用途/…

MATLAB求和∑怎么用?

MATLAB求和∑怎么用&#xff1f; 一&#xff1a;題目&#xff1a;求下列方程的和 二、代碼如下 1.syms函數 &#xff08;方法一) 代碼如下&#xff08;示例&#xff09;&#xff1a; 1. syms x 2. symsum((x.^22*x).^3,1,100) 3. 2.直接用循環 (方法二) 代碼如下&am…

每日算法-鏈表(2.兩數相加、24.兩兩交換鏈表中的節點、143.重排鏈表)

一.兩數相加 1.1題目描述 1.2題解思路 定義兩個指針l1,l2依次遍歷兩個鏈表&#xff0c;用變量add存儲l1加l2的值&#xff0c;將add的個位數取出來充當新節點的值&#xff0c;然后將add的個位數刪去&#xff0c;即add /10&#xff0c;循環此操作。 重點分析&#xff1a; 1.跟…

Flutter學習 滾動組件(1):ListView基本使用

目錄 一、ListView構造方法1.1 常規方法1.2 ListView.builder1.3 ListView.separated 二、自定義ListView樣式和布局&#xff1a;三、ListView性能優化&#xff1a;總結&#xff1a; 一、ListView構造方法 主要以下幾種方法&#xff1a; 常規方法&#xff0c;直接使用默認的構…

ESLint常見錯誤

1、Strings must use singlequote —— 字符串必須使用單引號 2、Extra semicolon semi——額外的分號&#xff1a;一行語句結尾不能添加分號 3、Unexpected trailing comma —— 行尾多了一個逗號 4、Newline required at end of file but not found ——文件結尾必須要新加…

Windows進行磁盤分區/擴容

Windows進行磁盤分區/擴容 導航 文章目錄 Windows進行磁盤分區/擴容導航分區教程壓縮卷教程 用Windows自帶的磁盤管理進行分區/擴容&#xff0c;但有個東西需要說明下是&#xff1a; 物理特性限制 磁盤分區的物理特性決定了擴容操作的方向。在磁盤上&#xff0c;數據是線性存儲…

獲取類路徑

分析 String pathThread.currentThread().getContextClassLoader().getResource("log").getPath(); 這行代碼用于獲取類路徑(classpath)下名為"log"的資源的文件系統路徑&#xff0c;我來詳細解析它的執行過程和潛在問題&#xff1a; 1. 代碼分解解析 j…