Google Guava / 等价 / 不同的 equals() 和 hashCode() 方法实现
我希望能够在两个 equals-Implementations 之间切换,但我不确定 Google Guava 的 Equivalence 类是否提供此功能。假设我有两个 equals 方法 equalsContent() 和 equalsKeys() 或类似的方法,我想以某种方式将 equals 方法委托给两个私有方法之一(两个 hashCode 方法也是如此)。
好吧,我不知何故不确定 Equivalence 抽象类和 Equivalences 类(静态方法)的用法是什么。
此外,您将如何实现上述所需的属性?我可以使用另一种方法,它简单地为值设置一个标志或一个枚举,并使用两个抽象方法(equals()、hashCode())在枚举内实现两个 equals 和 hash 方法,然后简单地调用 enum.equals() 或 enum equals() 和 hashCode() 方法中的 .hashCode() 。你怎么认为?
I want to be able to switch between two equals-Implementations, but I'm not sure if the Equivalence
class of Google Guava maybe provides this functionality. Let's say I have two equals methods equalsContent() and equalsKeys() or something like that I somehow want to delegate the equals method to one of the two private methods (and the same for the two hashCode methods).
Well, I'm somehow not sure what the usage of the Equivalence
abstract class and the Equivalences
class (static methods) is.
Besides, how would you implement the desired properties described above? I could use another method which simply sets a flag or an enum to the value and implement the two equals and hash methods inside an enum with two abstract methods (equals(), hashCode()) and simply call enum.equals() or enum.hashCode() in the equals() and hashCode() method. What do you think?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为从面向对象的角度来看,枚举方法是有意义的,但它很危险。它可能会破坏
equals()
和hashCode()
契约(自反性、对称性和传递性)。例如,在同一个 Set 中插入使用第一个等价策略的实例和使用第二个等价策略的实例会导致问题。如果您想要不同的等价关系,则应该将它们排除在类之外。
Equivalence
可以让您做到这一点:通过实现 Equivalence 并覆盖doHash()
和doEquivalent( )
方法。然后,当您想要使用基于一种或另一种等价的
Collection
时,您可以使用Equivalence.wrap()
。例如,您可以通过执行以下操作来模拟IdentityHashSet
:当然,您可以使用
ForwardingSet
自动包装/展开元素。此 Guava 问题中提供了更多信息。
I think the enum approach would make sense from an object-oriented point of view, but it's dangerous. It could break the
equals()
andhashCode()
contract (reflexivity, symmetry, and transitivity). For example, inserting an instance that uses the first equivalence strategy and an instance that uses the second equivalence strategy in the sameSet
would cause problems.If you want different equivalence relationships, you should keep those out of your class.
Equivalence
lets you do just that: you extract the equivalence logic (equals() / hashCode()) by implementing Equivalence and overriding thedoHash()
anddoEquivalent()
methods.Then, when you want to use a
Collection
based on one equivalence or the other, you useEquivalence.wrap()
. For example, you could emulate anIdentityHashSet
by doing:Of course, you could use
ForwardingSet
to automate the wrapping / unwrapping of your elements.There is more info in this Guava issue.