前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java实例属性比较引发的一些思考

Java实例属性比较引发的一些思考

作者头像
猫老师的叶同学
发布2023-03-14 09:42:51
2020
发布2023-03-14 09:42:51
举报
文章被收录于专栏:中间件的探究中间件的探究

Java实例属性比较引发的一些思考

1、缘起

在编写一个判断数据是否变化的逻辑中,比如一个User类,需要比较两个User的实例属性是否全部相同,以此来判断属性值是否已经发生改变。

2、创建测试类

也是较为原始或无脑的写法,举个例子 创建比较的实体类

代码语言:javascript
复制
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Integer id;
    private String name;
    private BigDecimal money;
}

编写测试类

代码语言:javascript
复制
public class PropertiesTest {

    public static void main(String[] args) {
        // 1、定义两个User实例
        User user1 = new User(1, "zhangsan", new BigDecimal("25.7").setScale(2, RoundingMode.HALF_UP));
        User user2 = new User(1, "zhangsan", new BigDecimal("25.70").setScale(2, RoundingMode.HALF_UP));
        // 2、比较方法
    }
 }
方法一:普通的if-else判断
代码语言:javascript
复制
public static void main(String[] args) {
    // 1、定义两个User实例
     User user1 = new User(1, "zhangsan", new BigDecimal("25.7").setScale(2, RoundingMode.HALF_UP));
     User user2 = new User(1, "zhangsan", new BigDecimal("25.70").setScale(2, RoundingMode.HALF_UP));
     boolean flag = compareOne(user1, user2);
     System.out.println(flag);
 }
    
 /**
  * 方法一: 是否if
  * @param user1 实例1
  * @param user2 实例2
  * @return  属性值是否相同
  */
 public static boolean compareOne(User user1, User user2){
     if (!Objects.equals(user1.getId(), user2.getId())) {
         return false;
     } else if (!Objects.equals(user1.getName(), user2.getName())) {
         return false;
     } else return Objects.equals(user1.getMoney(), user2.getMoney());
 }

优点:实体类中需要比较字段较少时,代码逻辑简单。 缺点:实体类中需要比较的字段较多时,代码重复显得冗余。

方法二:通过反射遍历属性字段取得属性值
代码语言:javascript
复制
public static void main(String[] args) {
     // 1、定义两个User实例
     User user1 = new User(1, "zhangsan", new BigDecimal("25.7").setScale(2, RoundingMode.HALF_UP));
     User user2 = new User(1, "zhangsan", new BigDecimal("25.70").setScale(2, RoundingMode.HALF_UP));
//        boolean flag = compareOne(user1, user2);
     boolean flag = compareTwo(user1, user2, new String[]{"id", "name", "money"});
     System.out.println(flag);
 }
 
/**
 * 方法二: 使用反射
 * @param user1 实例1
 * @param user2 实例2
 * @return  属性值是否相同
 */
public static boolean compareTwo(User user1, User user2, String[] fields){
    boolean flag = true;
    try {
        for (String field : fields){
            // 实例1
            Field field1 = user1.getClass().getDeclaredField(field);
            field1.setAccessible(true);
            Object value1 = field1.get(user1);
            // 实例2
            Field field2 = user2.getClass().getDeclaredField(field);
            field2.setAccessible(true);
            Object value2 = field2.get(user2);
            if ( !Objects.equals(value1, value2) ) {
                flag = false;
                break;
            }

        }
    } catch (NoSuchFieldException | IllegalAccessException e) {
        flag = false;
        e.printStackTrace();
    }
    return flag;
}

优点:针对于实体类中需要比较字段较多的情况,可以针对封装工具方法。 缺点:实体类中需要比较的字段较多时,反射性能不是较优。

方法三:使用hutool工具

引入hutool工具包

代码语言:javascript
复制
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
     <groupId>cn.hutool</groupId>
     <artifactId>hutool-all</artifactId>
     <version>5.8.15</version>
</dependency>
代码语言:javascript
复制
public static void main(String[] args) {
    // 1、定义两个User实例
    User user1 = new User(1, "zhangsan", new BigDecimal("25.7").setScale(2, RoundingMode.HALF_UP));
    User user2 = new User(1, "zhangsan", new BigDecimal("25.70").setScale(2, RoundingMode.HALF_UP));
//        boolean flag = compareOne(user1, user2);
//        boolean flag = compareTwo(user1, user2, new String[]{"id", "name", "money"});
    boolean flag = compareThree(user1, user2);
    System.out.println(flag);
}

/**
 * 方法三: hutool工具类
 * @param user1 实例1
 * @param user2 实例2
 * @return  属性值是否相同
 */
public static boolean compareThree(User user1, User user2){
    Map<String, Object> map1 = BeanUtil.beanToMap(user1, true, true);
    Map<String, Object> map2 = BeanUtil.beanToMap(user2, true, true);
    if (map1.keySet().size() != map2.keySet().size()) {
        return false;
    }
    for (Map.Entry<String, Object> str : map1.entrySet()){
        if ( !Objects.equals(map2.get(str.getKey()), str.getValue())) {
            return false;
        }
    }
    return true;
}

优点:代码简洁,直接使用第三方工具包接口,比较逻辑简单 缺点:需要引入第三方jar包

总结

以上是对类实例字段值比较的一些思考,希望可以带来一些火花。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-03-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Java实例属性比较引发的一些思考
    • 1、缘起
      • 2、创建测试类
        • 方法一:普通的if-else判断
          • 方法二:通过反射遍历属性字段取得属性值
            • 方法三:使用hutool工具
              • 总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档