关于在集合中对象比较属性值的问题

关于在集合中对象比较属性值的问题

  • 1 问题说明
  • 2 问题排查
  • 3 总结及伪代码

楼主在最近遇到一个场景,项目中有一个校验。 需要将数据库查询的集合对象与前端传递的集合对象进行比较,看数据是否被修改。

1 问题说明

基于上面项目需求,项目为较老的传统项目,没使用Lombok插件(划重点),实体类和DTO,BO对象都是原有get、set方法等等。项目之前运行正常,且没有任何问题。接到新需求,需要多添加某些字段。

再一顿CRUD的基础操作之后,代码加上去,实体类对应的页面增删改查都没有问题。于是极度自信,提交代码。(O(∩_∩)O)

在代码中上述校验处,突然报错,直接给我整懵逼。

2 问题排查

本着哪里有问题,就解决哪里的思维。

  • 首先,怀疑是不是前端传值有误差(前端问题),在集合比较处添加上相关日志,抓取日志,分析对比数据后,发现数据没有问题,无论是前端传参,还是后端数据库查询。

  • 问题已经很明显了,加的代码有问题。(不可能,绝对不可能) ,虽然吧,但是可以确认就是自己加出问题了。然后看了下,集合比较的方法是collections.subtract()。这个方法常用来比较两个集合的差值,而且一般用在基本的数据类型比较,如字符串集合,数字集合等等。再对象集合比较,用的还是较少。

已经知道了是这个方法比较的问题,查看了一下实体类和DTO对象新增字段,set、get方法也都给写了,包括toString方法也重写了。看了两个对象一下子又没思路了,突然想到比较两个对象值,需要重写equals和hashcode方法。(掐自己一下)检查了一下实体类和DTO对象,因实体类不做比较,故没加equals和hashcode方法。而DTO对象因用来做了比较,所以都重写了这两个方法。看了一下DTO对象中,仅仅只加了属性和get、set方法以及toString方法。 按照思路,在equals和hashcode方法中加上新增字段,启动项目测试,成功了!(撒花

3 总结及伪代码

思考了一下,问题的出现。

因平时接触新项目,都是用lombok插件,对于对象的字段的删减,平时只需要注意对象本身以及xml文件中的sql拼写,对于对象基本的toString,equals,hashcode等方法关注不多。(基本忽视)在老项目中,没使用lombok插件,没人来帮忙写这些基础的对象方法,所以在一个简单的增减字段的需求时,需要花一些时间来关注对象本身的方法。这也正说明lombok插件也是蛮方便,减少了这类小问题。

伪代码

原有对象

public class UserDTO {

    private String id;
    
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "UserDTO{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserDTO userDTO = (UserDTO) o;
        return Objects.equals(id, userDTO.id) &&
                Objects.equals(name, userDTO.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}

添加新字段

public class UserDTO {

    private String id;

    private String name;

    // 新加字段手机号
    private String phone;

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "UserDTO{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserDTO userDTO = (UserDTO) o;
        return Objects.equals(id, userDTO.id) &&
                Objects.equals(name, userDTO.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}

比较逻辑代码

// 前端传参数
List<UserDTO> reqList = new ArrayList();
// 数据库查询
List<UserDTO> respList = new ArrayList();
// 两个集合差集
List<UserDTO> resultList = CollectionUtils.subtract(reqList,respList)
// 判断集合中数据是否改变
if(CollectionUtils.isNotEmpty(resultList)){
    // 前端数据中,传了手机号,一直识别不出来,添加名称则可以识别出来,在DTO对象中equals方法中添加手机号即可
}

最后状态

public class UserDTO {

    private String id;

    private String name;

    private String phone;

	// 省略set/get方法

    @Override
    public String toString() {
        return "UserDTO{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserDTO userDTO = (UserDTO) o;
        return Objects.equals(id, userDTO.id) &&
                Objects.equals(name, userDTO.name) &&
                Objects.equals(phone, userDTO.phone);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, phone);
    }
}

你可能感兴趣的:(学习笔记,java,前端,数据库)