简化相等判断:如何优化Account与UpdateAccount对象差异对比代码?
问题:如何更优雅地对比Account与UpdateAccount的属性差异
现有实体类定义
Account类
@Getter @Setter @AllArgsConstructor @NoArgsConstructor public class Account { private String id; private String section; private String name; private String type; private String username; }
UpdateAccount类
@Getter @Setter @AllArgsConstructor @NoArgsConstructor public class UpdateAccount { private String section; private String name; }
当前属性差异对比实现
public class App { public static void main(String[] args){ Account account = new Account("123", "sectionA", "p1", "test", "TestUser1"); UpdateAccount updateAccount = new UpdateAccount("sectionA", "p11"); Set<String> diff = new HashSet<>(); if(!updateAccount.getName().equals(account.getName())){ diff.add("name"); } if(!updateAccount.getSection().equals(account.getSection())){ diff.add("section"); } System.out.println(diff); } }
替代实现方案
1. 抽取工具方法减少重复代码
把属性对比逻辑封装成通用方法,避免重复编写equals判断,同时用Objects.equals规避空指针风险:
import java.util.HashSet; import java.util.Objects; import java.util.Set; public class App { public static void main(String[] args){ Account account = new Account("123", "sectionA", "p1", "test", "TestUser1"); UpdateAccount updateAccount = new UpdateAccount("sectionA", "p11"); Set<String> diff = new HashSet<>(); checkDiff(diff, "name", updateAccount.getName(), account.getName()); checkDiff(diff, "section", updateAccount.getSection(), account.getSection()); System.out.println(diff); } private static void checkDiff(Set<String> diffSet, String fieldName, String newValue, String oldValue) { if (!Objects.equals(newValue, oldValue)) { diffSet.add(fieldName); } } }
2. 反射实现通用属性对比
如果后续属性频繁新增或修改,反射可以自动遍历UpdateAccount的所有属性,无需手动添加判断逻辑:
import java.lang.reflect.Field; import java.util.HashSet; import java.util.Objects; import java.util.Set; public class App { public static void main(String[] args){ Account account = new Account("123", "sectionA", "p1", "test", "TestUser1"); UpdateAccount updateAccount = new UpdateAccount("sectionA", "p11"); Set<String> diff = findDiffFields(updateAccount, account); System.out.println(diff); } private static Set<String> findDiffFields(Object updateObj, Object originalObj) { Set<String> diffFields = new HashSet<>(); Field[] updateFields = updateObj.getClass().getDeclaredFields(); for (Field field : updateFields) { field.setAccessible(true); try { Object updateValue = field.get(updateObj); Object originalValue = originalObj.getClass().getDeclaredField(field.getName()).get(originalObj); if (!Objects.equals(updateValue, originalValue)) { diffFields.add(field.getName()); } } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); } } return diffFields; } }
注意:反射存在轻微性能开销,适合属性较多且变动频繁的场景。
3. 基于Map映射的属性对比
将两个对象的目标属性转成Map,通过遍历键值对完成对比,逻辑直观易懂:
import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Objects; import java.util.Set; public class App { public static void main(String[] args){ Account account = new Account("123", "sectionA", "p1", "test", "TestUser1"); UpdateAccount updateAccount = new UpdateAccount("sectionA", "p11"); Map<String, String> updateMap = new HashMap<>(); updateMap.put("name", updateAccount.getName()); updateMap.put("section", updateAccount.getSection()); Map<String, String> originalMap = new HashMap<>(); originalMap.put("name", account.getName()); originalMap.put("section", account.getSection()); Set<String> diff = new HashSet<>(); for (Map.Entry<String, String> entry : updateMap.entrySet()) { if (!Objects.equals(entry.getValue(), originalMap.get(entry.getKey()))) { diff.add(entry.getKey()); } } System.out.println(diff); } }
内容的提问来源于stack exchange,提问作者xxestter
相关产品推荐
相关产品推荐

