关门了。
这个问题不符合
堆栈溢出指南
..。它目前不接受答案。
想要改进这个问题吗?
更新问题,使其成为
主题
堆栈溢出。
4个月前就关门了。
改进这个问题
如何根据测试中的字段值“深入”-compare两个没有实现equals方法的对象?
原始问题(由于缺乏精确度而关闭,因此不符合SO标准),出于文档目的而保留:
我正在尝试为各种clone()操作,我想知道在某个地方是否有一个现有的类能够获取相同类型的两个对象,进行深入的比较,并判断它们是否相同?
发布于 2009-09-19 17:34:31
单位
具有以下功能:
通过反射进行相等断言,具有不同的选项,如忽略Java默认值/空值和忽略集合顺序
发布于 2010-09-30 11:14:14
我喜欢这个问题!主要是因为它很少被回答或者回答得不好。好像还没有人弄明白这一点。处女地:)
首先,不要思考关于使用equals..。的合同equals如在javadoc中定义的,是等价关系(自反的、对称的和传递的),
注释
一种平等的关系。为此,它还必须是反对称的。的唯一实现equals也就是说(或者可能是)真正的平等关系是java.lang.Object..。即使你使用了equals将图表中的所有内容进行比较,违约的风险相当高。正如Josh Bloch在有效的Java,equals的契约很容易被破坏:
“根本没有办法在保留equals契约的同时扩展一个可实例化的类并添加一个方面。”
除此之外,布尔方法到底对你有什么好处呢?将原始和克隆之间的所有差异都封装起来会很好,你不这样认为吗?此外,我在这里假设您不想为图形中的每个对象编写/维护比较代码,而是希望随着源代码的变化而扩展。
所以,你真正想要的是某种状态比较工具。该工具的实现方式实际上取决于您的域模型的性质和性能限制。根据我的经验,没有通用的灵丹妙药。而且它
意志
在大量迭代中保持缓慢。但是对于测试克隆操作的完整性,它可以很好地完成这项工作。最好的两个选择是序列化和反射。
您将遇到一些问题:
集合顺序:如果两个集合持有相同的对象,但顺序不同,那么它们是否应该被视为相似?
忽略哪些字段:瞬态?静电?
类型等价:字段值应该是完全相同的类型吗?或者其中一个可以扩展另一个?
还有更多但我忘了..。
XStream非常快,与XMLUnit相结合,只需几行代码就可以完成这项工作。XMLUnit很好,因为它可以报告所有的差异,或者只停留在它找到的第一个差异。它的输出包括不同节点的xpath,这很好。默认情况下,它不允许无序集合,但可以配置为这样做。注入一个特殊的差异处理程序(称为DifferenceListener)允许您指定处理差异的方式,包括忽略顺序。但是,只要您想做最简单的自定义之外的任何事情,就会变得很难编写,并且细节往往会绑定到特定的域对象。
我个人的偏好是使用反射遍历所有声明的字段,并深入到每个字段,在执行过程中跟踪差异。警告:除非你喜欢堆栈溢出异常,否则不要使用递归。使用堆栈将事物保持在范围内(使用LinkedList或其他什么)。我通常忽略瞬态和静态字段,并跳过我已经比较过的对象对,这样如果有人决定编写自引用代码,我就不会陷入无限循环(然而,我总是比较原始包装器,因为相同的对象引用经常被重用)。您可以预先配置为忽略集合排序和特殊类型或字段,但我喜欢通过注释在字段本身上定义我的状态比较策略。IMHO,这正是注释的目的,使有关类的元数据在运行时可用。类似于:
@StatePolicy(unordered=true, ignore=false, exactTypesOnly=true)
private List _mylist;
我认为这实际上是一个非常困难的问题,但完全可以解决!一旦你有了适合你的东西,它就真的,真的,很方便:)
所以,祝你好运。如果你想出了一些纯粹的天才的东西,别忘了分享!
发布于 2012-04-26 07:59:24
参见java-util中的DeepEquals和DeepHashCode():
https://github.com/jdereg/java-util
这个类做的正是原始作者所要求的。
https://stackoverflow.com/questions/1449001
复制相似问题