【填坑往事】使用Rxjava2的distinct操作符處理自定義資料型別去重的問題

宋者為王發表於2022-01-08

       最近碰到一個問題,自定義資料型別列表中出現了重複資料,需要去重。處理去重的辦法很多,比如藉助Set集合類,使用雙重迴圈拿每一個元素和其他元素對比等。這裡介紹一種簡單而且比較優雅的方式:使用Rxjava2中的distinct操作符來實現。

       網上介紹這種方式的文章非常多,但基本上都是拿整數型別資料來演示,比如:

1 Observable.just(1, 1, 2, 2, 3, 4).distinct().subscribe(new Consumer<Integer>() {
2             @Override
3             public void accept(Integer integer) throws Exception {
4                 Log.d(TAG, "[distinct-accept]integer = " + integer);
5             }
6         });

但實際工作中碰到的資料型別卻是自定義型別,看到上述程式碼後本人還是有時有點手足無措,沒法直接拿到依葫蘆畫瓢。後來自己研究了一下,在上述程式碼基礎上轉了一個彎,解決了這個問題,下面記錄一下。

使用的自定義型別為:

 1 public class UserInfo {
 2     private String userId;
 3     private String userName;
 4 
 5     public UserInfo(String userId, String userName) {
 6         this.userId = userId;
 7         this.userName = userName;
 8     }
 9 
10     public String getUserId() {
11         return userId;
12     }
13 
14     public void setUserId(String userId) {
15         this.userId = userId;
16     }
17 
18     public String getUserName() {
19         return userName;
20     }
21 
22     public void setUserName(String userName) {
23         this.userName = userName;
24     }
25 
26     @Override
27     public boolean equals(Object o) {
28         if (this == o) return true;
29         if (o == null || getClass() != o.getClass()) return false;
30         UserInfo userInfo = (UserInfo) o;
31         return Objects.equals(userId, userInfo.userId);
32     }
33 
34     @Override
35     public int hashCode() {
36         return Objects.hash(userId);
37     }
38 
39     @Override
40     public String toString() {
41         return "UserInfo{" +
42                 "userId='" + userId + '\'' +
43                 ", userName='" + userName + '\'' +
44                 '}';
45     }
46 }

測試程式碼為

 1 private void testDistinct() {
 2     List<UserInfo> userInfoList = new ArrayList<>();
 3     userInfoList.add(new UserInfo("id-0", "name-0"));
 4     for (int i = 0; i < 10; i++) {
 5         userInfoList.add(new UserInfo("id-" + i, "name-" + i));
 6     }
 7     Log.d(TAG, "[testDistinct]去重前");
 8     for (UserInfo userInfo : userInfoList) {
 9         Log.d(TAG, "[testDistinct]userInfo = " + userInfo.toString());
10     }
11     Log.d(TAG, "[testDistinct]去重後");
12     Observable.fromIterable(userInfoList).distinct().subscribe(new Consumer<UserInfo>() {
13         @Override
14         public void accept(UserInfo userInfo) throws Exception {
15             Log.d(TAG, "[distinct-accept]userInfo = " + userInfo.toString());
16         }
17     });
18 }

日誌

 1 2022-01-08 16:41:31.858 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [testDistinct]去重前
 2 2022-01-08 16:41:31.858 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [testDistinct]userInfo = UserInfo{userId='id-0', userName='name-0'}
 3 2022-01-08 16:41:31.858 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [testDistinct]userInfo = UserInfo{userId='id-0', userName='name-0'}
 4 2022-01-08 16:41:31.858 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [testDistinct]userInfo = UserInfo{userId='id-1', userName='name-1'}
 5 2022-01-08 16:41:31.858 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [testDistinct]userInfo = UserInfo{userId='id-2', userName='name-2'}
 6 2022-01-08 16:41:31.858 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [testDistinct]userInfo = UserInfo{userId='id-3', userName='name-3'}
 7 2022-01-08 16:41:31.858 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [testDistinct]userInfo = UserInfo{userId='id-4', userName='name-4'}
 8 2022-01-08 16:41:31.858 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [testDistinct]userInfo = UserInfo{userId='id-5', userName='name-5'}
 9 2022-01-08 16:41:31.858 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [testDistinct]userInfo = UserInfo{userId='id-6', userName='name-6'}
10 2022-01-08 16:41:31.858 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [testDistinct]userInfo = UserInfo{userId='id-7', userName='name-7'}
11 2022-01-08 16:41:31.858 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [testDistinct]userInfo = UserInfo{userId='id-8', userName='name-8'}
12 2022-01-08 16:41:31.858 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [testDistinct]userInfo = UserInfo{userId='id-9', userName='name-9'}
13 2022-01-08 16:41:31.858 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [testDistinct]去重後
14 2022-01-08 16:41:31.870 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [distinct-accept]userInfo = UserInfo{userId='id-0', userName='name-0'}
15 2022-01-08 16:41:31.871 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [distinct-accept]userInfo = UserInfo{userId='id-1', userName='name-1'}
16 2022-01-08 16:41:31.871 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [distinct-accept]userInfo = UserInfo{userId='id-2', userName='name-2'}
17 2022-01-08 16:41:31.871 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [distinct-accept]userInfo = UserInfo{userId='id-3', userName='name-3'}
18 2022-01-08 16:41:31.871 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [distinct-accept]userInfo = UserInfo{userId='id-4', userName='name-4'}
19 2022-01-08 16:41:31.871 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [distinct-accept]userInfo = UserInfo{userId='id-5', userName='name-5'}
20 2022-01-08 16:41:31.871 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [distinct-accept]userInfo = UserInfo{userId='id-6', userName='name-6'}
21 2022-01-08 16:41:31.871 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [distinct-accept]userInfo = UserInfo{userId='id-7', userName='name-7'}
22 2022-01-08 16:41:31.871 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [distinct-accept]userInfo = UserInfo{userId='id-8', userName='name-8'}
23 2022-01-08 16:41:31.871 12668-12668/com.beantechs.rxjavademo D/rxjava_demo: [distinct-accept]userInfo = UserInfo{userId='id-9', userName='name-9'}

日誌中紅色部分顯示了去重效果。

       本示例中是把具有相同userId的物件視為同一個物件,所有在UserInfo類中重寫了equals()方法和hashCode()方法,這是關鍵點。如果判斷是否為同一物件的條件有變化,就需要相應地重寫equals()方法和hashCode()方法。

   

相關文章