最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?Stream去重常見的多種方法及示例

 更新時間:2025年04月12日 10:59:42   作者:碼農(nóng)界趙子龍  
這篇文章主要介紹了Java?Stream中實現(xiàn)去重的多種方法,包括使用distinct()、Collectors.toMap、filter和groupingBy等,詳細說明了每種方法的應用場景和示例代碼,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

在Java Stream中實現(xiàn)去重有多種方法,具體取決于需求和場景。以下是常見的幾種方法及示例:

1. 使用 distinct() 方法

適用于對象已正確實現(xiàn) equals() 和 hashCode(),基于對象整體去重并保留順序:

List<Person> uniquePersons = persons.stream()
                                    .distinct()
                                    .collect(Collectors.toList());

2. 根據(jù)對象的屬性去重

方法一:使用 Collectors.toMap

根據(jù)屬性作為鍵,保留第一個或最后一個元素,支持順序(使用 LinkedHashMap):

// 保留第一個出現(xiàn)的元素
List<Person> uniqueByName = persons.stream()
    .collect(Collectors.toMap(
        Person::getName,
        Function.identity(),
        (oldP, newP) -> oldP, // 保留舊值(第一個)
        LinkedHashMap::new    // 保持插入順序
    ))
    .values().stream()
    .collect(Collectors.toList());

// 保留最后一個出現(xiàn)的元素
List<Person> uniqueByNameLast = persons.stream()
    .collect(Collectors.toMap(
        Person::getName,
        Function.identity(),
        (oldP, newP) -> newP  // 保留新值(最后一個)
    ))
    .values().stream()
    .collect(Collectors.toList());

方法二:使用 filter 和線程安全的 Set

適用于并行流,但可能不保留順序:

// 并行流去重(不保證順序)
Set<String> seen = ConcurrentHashMap.newKeySet();
List<Person> uniqueByName = persons.parallelStream()
    .filter(p -> seen.add(p.getName()))
    .collect(Collectors.toList());

// 順序流去重(保留順序)
Set<String> seenOrdered = new HashSet<>();
List<Person> uniqueByNameOrdered = persons.stream()
    .filter(p -> seenOrdered.add(p.getName()))
    .collect(Collectors.toList());

方法三:使用 groupingBy

分組后取每組的第一個元素,保持順序:

List<Person> uniqueByName = persons.stream()
    .collect(Collectors.groupingBy(
        Person::getName,
        LinkedHashMap::new,    // 保持插入順序
        Collectors.toList()
    ))
    .values().stream()
    .map(group -> group.get(0)) // 取第一個元素
    .collect(Collectors.toList());

3. 根據(jù)字符串長度去重示例

List<String> words = Arrays.asList("apple", "banana", "orange", "grape", "kiwi");
List<String> uniqueByLength = words.stream()
    .collect(Collectors.toMap(
        String::length,
        Function.identity(),
        (oldVal, newVal) -> oldVal,
        LinkedHashMap::new
    ))
    .values().stream()
    .collect(Collectors.toList());
// 結(jié)果: ["apple", "banana", "kiwi"](保留順序)

4. 自定義去重借助Filter 實現(xiàn):

自定義一個 Predicate 函數(shù),用一個 Set 來記錄已經(jīng)出現(xiàn)過的元素,然后過濾掉重復的元素。

//定義一個Predicate函數(shù)
private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    Set<Object> sets = ConcurrentHashMap.newKeySet();
    return t -> sets.add(keyExtractor.apply(t));
}

//根據(jù)age屬性去重
list.stream().filter(distinctByKey(s -> s.getAge()))
        .forEach(System.out::println);

附:java中使用stream流根據(jù)對象中的某一字段進行去重

在開發(fā)中經(jīng)常會遇到數(shù)據(jù)去重的,單個基本類型的集合去重比較容易,比如String、Integer,直接使用流中的distinct方法去重即可。但是遇到對象集合,需要使用對象中的某個字段去重就不能使用這個方法了。可以在流式編程中加入TreeSet,TreeSet是一個有序且不重復的有序集合。以用戶User數(shù)據(jù)位列:

List<User> list = userService.list();
        list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing( f -> f.getDeptName()+":"+f.getStatus()))),ArrayList::new));

這里是根據(jù)用戶的部門以及用戶的狀態(tài)進行數(shù)據(jù)去重,將用戶的部門以及狀態(tài)拼接位一個字符串進行去重,這樣stream內(nèi)部會將整個user集合數(shù)據(jù)組裝成這樣進行整體去重,這樣去重下來的數(shù)據(jù)就是,每一個部門中只會存在一個狀態(tài)的部門人員數(shù)據(jù),這里是舉個例子,在實際環(huán)境中,你可以將User換成自己想要去重的實體集合。

總結(jié)

  • distinct():簡單高效,適用于對象整體去重。
  • toMap 或 groupingBy:靈活,支持按屬性去重,可控制保留順序。
  • filter + Set:適合并行流,但需注意線程安全和順序問題。

根據(jù)具體場景選擇最合適的方法,確保代碼簡潔且性能良好。

到此這篇關于Java Stream去重常見的多種方法及示例的文章就介紹到這了,更多相關Java Stream去重方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Maven導入依賴時爆紅的幾種解決方法

    Maven導入依賴時爆紅的幾種解決方法

    使用idea建立maven項目,maven導入依賴報紅,本文主要介紹了Maven導入依賴時爆紅的幾種解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-04-04
  • Java數(shù)組反轉(zhuǎn)方式

    Java數(shù)組反轉(zhuǎn)方式

    這篇文章主要介紹了Java數(shù)組反轉(zhuǎn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • springboot基于過濾器實現(xiàn)接口請求耗時統(tǒng)計操作

    springboot基于過濾器實現(xiàn)接口請求耗時統(tǒng)計操作

    這篇文章主要介紹了springboot基于過濾器實現(xiàn)接口請求耗時統(tǒng)計操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Java加權負載均衡策略實現(xiàn)過程解析

    Java加權負載均衡策略實現(xiàn)過程解析

    這篇文章主要介紹了Java加權負載均衡策略實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • SpringMVC框架實現(xiàn)上傳圖片的示例代碼

    SpringMVC框架實現(xiàn)上傳圖片的示例代碼

    本篇文章主要介紹了SpringMVC框架實現(xiàn)上傳圖片的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • SpringBoot處理 CORS 跨域的方法詳解

    SpringBoot處理 CORS 跨域的方法詳解

    Springboot跨域問題,是當前主流web開發(fā)人員都繞不開的難題,CORS是一個W3C標準,全稱是”跨域資源共享”,本文將給大家詳細介紹SpringBoot 如何處理 CORS 跨域,感興趣的同學跟著小編一起來看看吧
    2023-07-07
  • 深度源碼解析Java 線程池的實現(xiàn)原理

    深度源碼解析Java 線程池的實現(xiàn)原理

    如何高效的使用這些資源就是程序員在平時寫代碼時候的一個努力的方向。本文要說的線程池就是一種對 CPU 利用的優(yōu)化手段。對Java 線程池的實現(xiàn)原理相關知識感興趣的朋友一起看看吧
    2021-05-05
  • Java通過模板替換實現(xiàn)excel的傳參填寫方式

    Java通過模板替換實現(xiàn)excel的傳參填寫方式

    文章介紹了使用Java模板替換功能來實現(xiàn)Excel文件的傳參填寫,通過將模板中的占位符(如$)進行轉(zhuǎn)義和替換,可以動態(tài)生成包含具體數(shù)據(jù)的Excel文件,這種方法適用于需要批量生成帶有個性化數(shù)據(jù)的Excel文檔的場景
    2025-12-12
  • Spring線程池的配置及使用ThreadPoolTaskExecutor過程

    Spring線程池的配置及使用ThreadPoolTaskExecutor過程

    本文主要介紹了Spring提供的線程池ThreadPoolTaskExecutor及其配置方式,以及FixedThreadPool線程池的使用注意事項,同時強調(diào)了計數(shù)器的使用可以保證線程池執(zhí)行順序
    2026-03-03
  • Java實現(xiàn)String轉(zhuǎn)Integer的四種方案對比

    Java實現(xiàn)String轉(zhuǎn)Integer的四種方案對比

    在Java項目開發(fā)中,經(jīng)常會有類型轉(zhuǎn)換處理,這篇文章主要為大家詳細介紹了Java實現(xiàn)String轉(zhuǎn)Integer的四種方案對比,感興趣的小伙伴可以了解下
    2026-03-03

最新評論

璧山县| 南靖县| 濉溪县| 大丰市| 丰宁| 富源县| 二手房| 象山县| 陆河县| 高尔夫| 信丰县| 安岳县| 温宿县| 乌兰浩特市| 湘潭市| 定边县| 罗甸县| 清水县| 哈巴河县| 东丽区| 永昌县| 广丰县| 崇信县| 满城县| 西峡县| 阳城县| 农安县| 赫章县| 石城县| 隆德县| 顺昌县| 禹州市| 都兰县| 馆陶县| 津市市| 敦煌市| 大港区| 新和县| 东乡| 香港| 蚌埠市|