Java?Stream去重常見的多種方法及示例
在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()); // 結果: ["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換成自己想要去重的實體集合。
總結
distinct()
:簡單高效,適用于對象整體去重。toMap
或groupingBy
:靈活,支持按屬性去重,可控制保留順序。filter
+Set
:適合并行流,但需注意線程安全和順序問題。
根據(jù)具體場景選擇最合適的方法,確保代碼簡潔且性能良好。
到此這篇關于Java Stream去重常見的多種方法及示例的文章就介紹到這了,更多相關Java Stream去重方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring中的@ConditionalOnProperty注解使用詳解
這篇文章主要介紹了Spring中的@ConditionalOnProperty注解使用詳解,在 spring boot 中有時候需要控制配置類是否生效,可以使用 @ConditionalOnProperty 注解來控制 @Configuration 是否生效,需要的朋友可以參考下2024-01-01Java實現(xiàn)批量查找與替換Excel文本的思路詳解
在 Java 中,可以通過find和replace的方法來查找和替換單元格的數(shù)據(jù),下面小編將以Excel文件為例為大家介紹如何實現(xiàn)Excel文件內(nèi)容的批量替換,感興趣的朋友跟隨小編一起看看吧2023-10-10Java的Struts2框架配合Ext JS處理JSON數(shù)據(jù)的使用示例
這篇文章主要介紹了Java的Struts2框架配合Ext JS處理JSON數(shù)據(jù)的使用示例,包括將Ext JS中的JSON數(shù)據(jù)解析為列表的方法,需要的朋友可以參考下2016-03-03SpringBoot中忽略實體類中的某個屬性不返回給前端的方法(示例詳解)
本文介紹了在Spring Boot中使用Jackson和Fastjson忽略實體類屬性不返回給前端的方法,在Jackson中,同時使用@JsonProperty和@JsonIgnore時,@JsonIgnore可能失效,Fastjson中可以使用@JSONField(serialize=false)來實現(xiàn),本文結合實例代碼介紹的非常詳細,需要的朋友參考下吧2024-11-11MyBatis新增數(shù)據(jù)時自增id的兩種寫法小結
本文介紹了在MyBatis中配置自增ID的兩種方法:一種是通過在Mapper文件中設置useGeneratedKeys和keyProperty,另一種是使用selectKey標簽,批量插入時,同樣采用useGeneratedKeys標簽,感興趣的可以了解一下2024-09-09關于springboot加載yml配置文件的no字段自動轉義問題
這篇文章主要介紹了關于springboot加載yml配置文件的no字段自動轉義問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02