确定2个对象之间的差异

时间:2014-01-23 02:15:36

标签: java algorithm object comparison

我的工作类似于审核日志,需要记录2个给定对象之间不同的字段。

例如,我有Foo类的这两个对象oldFoonewFoo。假设这个类有20多个字段。我想知道哪些字段有所不同 - newFoonulloldFoo的{​​{1}}中的字段是什么,但没有孤独者? newFoo中哪些字段的值已更改或设置为null

当然,我总能像这样愚蠢地做到这一点:

Map<String, List<Map<String, Object>> diff (Foo oldFoo, Foo newFoo)
{
   Map<String, List<Map<String, Object>> ret = new HashMap<String, List<Map<String, Object>>();
  List<Map<String, Object>> added = new ArrayList<Map<String, Object>>();
  List<Map<String, Object>> changed = new ArrayList<Map<String, Object>>();
  List<Map<String, Object>> removed = new ArrayList<Map<String, Object>>();

  if (newFoo.getField1() != null && oldFoo.getField1() == null)
  {
     added.add(new HashMap<String, Object>().put("fieldName", "field1")
                                            .put("oldValue", "")
                                            .put("newValue", newFoo.getField1());
  }
  else if (newFoo.getField1() == null && oldFoo.getField1() != null)
  {
     removed.add(new HashMap<String, Object>().put("fieldName", "field1")
                                              .put("oldValue", oldFoo.getField1())
                                              .put("newValue", "");
  }
  else if (newFoo.getField1() != null && oldFoo.getField1() != null && !newFoo.getField1().equals(oldFoo.getField1())
  {
     changed.add(new HashMap<String, Object>().put("fieldName", "field1")
                                              .put("oldValue", oldFoo.getField1())
                                              .put("newValue", newFoo.getField1());

  }  

  //keep going for *MORE THAN 20* fields... :(
  //...

  ret.put("CHANGED", changed);
  ret.put("ADDED", added);
  ret.put("REMOVED", removed);
  return ret;

}

但我确信必须有一个聪明的方法。 有什么建议吗?

*更新1 * 我尽量避免使用反射。

1 个答案:

答案 0 :(得分:0)

您可以使用反射来完成整个事情。

使用反射扫描对象中的每个字段,并建立一个具有不同值的每个字段的列表。

然后该代码可以与您喜欢的任何两个对象一起使用!

顺便说一句,我会创建一个Change类,其中包含fieldNameoldValuenewValue字段,而不是滥用哈希映射。该类将更清晰/更易读,运行更快,使用更少的内存等等。

没有反思你几乎没有选择。您可以使用注释执行某些操作(扫描注释而不是成员变量)。另一种选择是将类更改为HashMap,而根本没有成员变量。