gpt4 book ai didi

groovy - 在 groovy 中动态覆盖 `equals` 和 `hashCode`

转载 作者:行者123 更新时间:2023-12-01 02:25:03 26 4
gpt4 key购买 nike

如果我动态覆盖 equalshashCode类的方法,调用这些方法直接调用覆盖的版本,但将它们用于 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

最佳答案

调用toSet()List invokes the following code :

    Set<T> answer = new HashSet<T>(self.size());
answer.addAll(self);
return answer;

现在 HashSet (Java 类)没有 metaClass 的概念,因此看不到您的重载 hashCodeequals方法。因此,您会在您的套装中获得 2 件元素。

您可以调用 unique首先在你的名单上:
println( [a, b].unique().toSet().size() ) 

当这通过调用者时,所以知道 metaClass并且应该给你一个包含一个元素的集合。

在实践中,我会避​​免更改 hashCode通过元类方法。正如您所看到的,很难确切知道它何时会被处理,并且处理得好的事情可能不会期望 hashCode 时时发生变化。

关于groovy - 在 groovy 中动态覆盖 `equals` 和 `hashCode`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17210540/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com