Stream distinct根据list某个字段去重的解决方案

作者:@大吉 时间:2022-06-22 22:23:26 

需求:

List<UserPojo> users = new ArrayList<>();
//第一个user和第4个user应该是相等的,因为它们的name和address相等
//id   name     address    age
users.add(new UserPojo(1, "daji", "山东省青岛市", 19));
users.add(new UserPojo(2, "daji2", "山东省济南市", 20));
users.add(new UserPojo(3, "daji3", "北京市", 22));
users.add(new UserPojo(4, "daji, "山东省青岛市", 23));

上面有4个user,对其进行去重,去重逻辑是根据name字段和address字段来决定(name和address字段相等 ,即可判定这两个对象相等,不必关心其他字段是否相等)

因此:第一个user和第4个user应该是相等的,因为它们的name和address相等

解决方案

stream的distinct去重方法,是根据 Object.equals,和 Object.hashCode这两个方法来判断是否重复的。

所以我们可以利用这个特性 ,重写pojo的 Object.equals,和 Object.hashCode这两个方法,来实现。

1、重写Object.equals方法

@Override
   public boolean equals(Object o) {
       UserPojo thisPojo = (UserPojo) o;
       //只有name 和 address 相等,也算相等
       if (this.getName().equals(thisPojo.getName()) && this.getAddress().equals(thisPojo.getAddress())){
           return true;
       }else {
           return false;
       }
   }

2、重写Object.hashCode方法

重写hashCode需要根据你选择的字段重新计算。

本例就是根据name和address重新计算hashcode。规则如下图:

Stream distinct根据list某个字段去重的解决方案

最终方法:

@Override
   public int hashCode() {
       //根据name和address重新计算hashcode
       int result = getName().hashCode();
       //17是死值, jdk建议用17
       result = 17 * result + getAddress().hashCode();
       return result;
   }

3、使用distinct去重:

users = users.stream().distinct().collect(Collectors.toList());

结果(去重成功,去掉了一个重复值):

Stream distinct根据list某个字段去重的解决方案

问题到此成功解决

4、[可选方案] 继承pojo重写equals和hashcode

如果我们不想动原有的pojo,我们可以新建一个新的pojo,来继承原有的pojo。

1、 新建一个子类,继承UserPojo
2、 重写该子类的 equals方法和hashcode 方法
3、 将父类的全部数据灌入子类,对子类 使用stream的distinct去重

代码如下:

@Test
   void test15() {
       List<UserPojo> users = new ArrayList<>();
       //第一个user和第4个user应该是相等的,因为它们的name和address相等
       users.add(new UserPojo(1, "daji", "山东省青岛市", 19));
       users.add(new UserPojo(2, "daji2", "山东省济南市", 20));
       users.add(new UserPojo(3, "daji3", "北京市", 22));
       users.add(new UserPojo(4, "daji", "山东省青岛市", 23));
       /*
           解决方案:使用stream的distinct去重
           1、 新建一个子类,继承UserPojo
           2、 重写该子类的 equals方法和hashcode 方法
           3、 将父类的全部数据灌入子类,对子类 使用stream的distinct去重
        */
       List<OverrideEqualsPojo> overrideEqualsPojos = new ArrayList<>();
       for (UserPojo user : users) {
           OverrideEqualsPojo overrideEqualsPojo = new OverrideEqualsPojo();
           BeanUtils.copyProperties(user,overrideEqualsPojo);
           overrideEqualsPojos.add(overrideEqualsPojo);
       }
       overrideEqualsPojos = overrideEqualsPojos.stream().distinct().collect(Collectors.toList());
       System.out.println(overrideEqualsPojos);
   }

子类pojo代码:

package com.daji.stream;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Objects;
public class OverrideEqualsPojo extends UserPojo{
   public OverrideEqualsPojo(int id, String name, String address, int age) {
       super(id, name, address, age);
   }
   public OverrideEqualsPojo() {
   }
   @Override
   public boolean equals(Object o) {
       OverrideEqualsPojo thisPojo = (OverrideEqualsPojo) o;
       //只有name 和 address 相等,也算相等
       if (this.getName().equals(thisPojo.getName()) && this.getAddress().equals(thisPojo.getAddress())){
           return true;
       }else {
           return false;
       }
   }
   @Override
   public int hashCode() {
       //根据name和address重新计算hashcode
       int result = getName().hashCode();
       //17是死值, jdk建议用17
       result = 17 * result + getAddress().hashCode();
       return result;
   }
}

来源:https://blog.csdn.net/weixin_44757863/article/details/125659749

标签:Stream,distinct,去重
0
投稿

猜你喜欢

  • Java DWR内存泄漏问题解决方案

    2022-02-28 02:35:07
  • Android 文件数据存储实例详解

    2023-07-28 17:08:03
  • Java 高并发三:Java内存模型和线程安全详解

    2021-10-24 07:04:13
  • 常用Maven库,镜像库及maven/gradle配置(小结)

    2023-11-20 23:44:00
  • maven资源过滤打包后文件变大的处理方法

    2023-10-05 21:38:24
  • Flutter Widgets MediaQuery控件屏幕信息适配

    2023-06-29 04:48:21
  • SpringBoot 利用thymeleaf自定义错误页面

    2023-11-29 08:29:55
  • Java Set集合及其子类HashSet与LinkedHashSet详解

    2023-11-26 11:39:35
  • MyBatis-Plus 集成动态多数据源的实现示例

    2023-06-26 17:56:35
  • Java这个名字的来历与优势

    2023-03-27 18:28:40
  • java实现航空用户管理系统

    2023-11-24 02:42:37
  • Android 之BottomsheetDialogFragment仿抖音评论底部弹出对话框效果(实例代码)

    2023-08-06 01:01:56
  • spring webflux自定义netty 参数解析

    2023-07-26 18:38:25
  • Kafka 日志存储实现过程

    2021-11-01 05:04:00
  • Android基于SoftReference缓存图片的方法

    2023-07-13 00:53:21
  • Java基础之堆内存溢出的解决

    2023-11-10 20:06:30
  • Android实现人脸支付的示例代码

    2023-07-30 14:23:52
  • 通过实例解析Spring argNames属性

    2023-09-14 10:43:13
  • Spring boot2X负载均衡和反向代理实现过程解析

    2023-02-06 04:18:53
  • Java语言实现数据结构栈代码详解

    2021-12-09 16:15:05
  • asp之家 软件编程 m.aspxhome.com