使用Stream查List對象某屬性是否有重復
Java8開發中,針對List對象集合,常需要判斷某個屬性是否存在重復值。用Stream流處理能方便的得到結果。
練習一下stream的一些用法
測試示例Java代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
@Test public void t2() { List<User> list = new ArrayList<>(); User user1 = new User( "zhangsan" , "beijing" , 30 ); User user2 = new User( "zhangsan" , "beijing" , 40 ); User user3 = new User( "lisi" , "shanghai" , 35 ); User user4 = new User( "lisi" , "shanghai" , 28 ); User user5 = new User( "lisim" , "shanghai" , 32 ); list.add(user1); list.add(user2);list.add(user3); list.add(user4);list.add(user5); System.out.println( "原始數據:" +list); //判斷姓名是否有重復,練習使用java8的stream方法 //方法1. distinct, 直接比較大小,只知道是否有重復 List<String> collect1 = list.stream().map(User::getName).distinct().collect(Collectors.toList()); System.out.println(collect1.size()!=list.size()? "方法1-姓名有重復" : "無重復" ); //方法2.用戶姓名計數 Map<Object, Long> collect2 = list.stream().collect( Collectors.groupingBy( User::getName , Collectors.counting() ) ); System.out.println( "姓名重復計數情況:" +collect2); //篩出有重復的姓名 List<Object> collect3 = collect2.keySet().stream(). filter(key -> collect2.get(key) > 1 ).collect(Collectors.toList()); //可以知道有哪些姓名有重復 System.out.println( "方法2-重復的姓名 : " +collect3); //方法3,對重復的姓名保留計數 List<Map<String, Long>> collect4 = collect2.keySet().stream(). filter(key -> collect2.get(key) > 1 ).map(key -> { Map<String, Long> map = new HashMap<>(); map.put((String) key, collect2.get(key)); return map; }).collect(Collectors.toList()); System.out.println( "方法3-重復的姓名及計數:" +collect4); } |
運行結果,方便驗證是否是需要的樣子。
原始數據:[User(name=zhangsan, address=beijing, age=30), User(name=zhangsan, address=beijing, age=40), User(name=lisi, address=shanghai, age=35), User(name=lisi, address=shanghai, age=28), User(name=lisim, address=shanghai, age=32)]
方法1-姓名有重復
姓名重復計數情況:{lisi=2, zhangsan=2, lisim=1}
方法2-重復的姓名 : [lisi, zhangsan]
方法3-重復的姓名及計數:[{lisi=2}, {zhangsan=2}]
list的五種去重方式
面試中經常被問到的list如何去重,一般是口述,不需要代碼體現,這個時候,思維一定要清晰,可以羅列出集中去重的方法,以展現你對list數據結構,以及相關方法的掌握,體現你的java基礎學的是否牢固
下面,我就將五種方法逐一展現
新建一個list數組:
1
2
3
4
5
6
7
8
9
10
11
|
List list = new ArrayList(); list.add( 26 ); list.add( 39 ); list.add( 39 ); list.add( 39 ); list.add( 39 ); list.add( 5 ); list.add( 40 ); list.add( 39 ); list.add( 25 ); System.out.println(list); |
方法一:使用java8新特性stream進行List去重
1
2
3
|
List newList = list.stream().distinct().collect(Collectors.toList()); System.out.println(“java8新特性stream去重:”+newList); list.add( 39 ); |
方法二:雙重for循環去重
1
2
3
4
5
6
7
|
for ( int i = 0 ; i < list.size(); i++) { for ( int j = 0 ; j < list.size(); j++) { if (i!=j&&list.get(i)==list.get(j)) { list.remove(list.get(j)); } } } |
上面的方法研究后,確實有點小問題,下面放上優化后的方法(不推薦使用,速度太慢)
1
2
3
4
5
6
7
8
9
10
11
12
13
|
for ( int i = 0 ; i < list.size(); i++) { for ( int j = 0 ; j < list.size(); ) { // System.out.println(i+"-"+list.get(i)+"-"+j+"!!!!"+list.get(j)); if (i != j && list.get(i) == list.get(j)) { // System.out.println(j+":"+list.get(j)); list.remove(j); } else { j++; } } } System.out.println(“雙重 for 循環去重:”+list); list.add( 39 ); |
方法三:set集合判斷去重,不打亂順序
1
2
3
4
5
6
7
8
9
|
Set set1 = new HashSet(); List newList1 = new ArrayList(); for (Integer integer : list) { if (set1.add(integer)) { newList1.add(integer); } } System.out.println(“set集合判斷去重:”+list); list.add( 39 ); |
方法四:遍歷后判斷賦給另一個list集合
1
2
3
4
5
6
7
8
|
List newList2 = new ArrayList(); for (Integer integer : list) { if (!newList2.contains(integer)){ newList2.add(integer); } } System.out.println(“賦值新list去重:”+newList2); list.add( 39 ); |
方法五:set和list轉換去重
1
2
3
4
5
|
Set set2 = new HashSet(); List newList3 = new ArrayList(); set2.addAll(list); newList3.addAll(set2); System.out.println(“set和list轉換去重:”+newList3); |
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/lx12345_/article/details/113204658