在groovy中动态覆盖`equals`和`hashCode`
发布时间:2020-12-14 16:22:09 所属栏目:大数据 来源:网络整理
导读:如果我动态地重写类的equals和hashCode方法,则调用这些方法会直接调用重写版本,但将它们用于set会使用非重写版本.为什么会这样,是否仍然可以为所有用法动态覆盖这两种方法? class SuperClass { public boolean equals(Object other) { println 'non overrid
如果我动态地重写类的equals和hashCode方法,则调用这些方法会直接调用重写版本,但将它们用于set会使用非重写版本.为什么会这样,是否仍然可以为所有用法动态覆盖这两种方法?
class SuperClass { public boolean equals(Object other) { println 'non overridden equals called' false } public int hashCode() { println 'non overridden hashCode called' 1 } } SuperClass.metaClass.equals = { Object other -> println 'overridden equals called' true } SuperClass.metaClass.hashCode = { -> println 'overridden hashCode called' 1 } def a = new SuperClass() def b = new SuperClass() println a.hashCode() // overriden hashCode called println b.hashCode() // overriden hashCode called println a.equals(b) // overriden equals called println([a,b].toSet().size()) // non overriden methods called,returns 2 instead of 1 解决方法
在列表
invokes the following code上调用toSet():
Set<T> answer = new HashSet<T>(self.size()); answer.addAll(self); return answer; 现在HashSet(一个Java类)没有metaClass的概念,所以没有看到你重载的hashCode和equals方法.因此,您的套装中有2件物品. 您可以做的是首先在列表中调用unique: println( [a,b].unique().toSet().size() ) 因为这通过调用者所以知道metaClass并且应该给你一个包含一个元素的集合. 实际上,我会避免通过metaClass更改hashCode方法.正如您所看到的,很难确切知道何时处理它,以及处理得好的事情可能并不期望hashCode会随时改变. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |