加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

在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会随时改变.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读