Implementations of Google Guava / Equivalence / different equals () and hashCode ()

I want to be able to switch between two equals-Implementations, but I'm not sure if the Google Guava Equivalence class can provide this functionality. Let them say that I have two methods equalsContent () and equalsKeys () or something like this. I somehow want to delegate the equals method to one of two private methods (and the same for the two hashCode methods).

Well, I'm somehow not sure if using the abstract Equivalence class and the Equivalences class (static methods).

In addition, how would you implement the required properties described above? I could use another method that simply sets a flag or enumeration for the value and implements two equality and hash methods inside the enumeration with two abstract methods (equals (), hashCode ()) and simply calls enum.equals () or the .hashCode ( ) in the equals () and hashCode () methods. What do you think?

+4
source share
1 answer

I think the enum approach would make sense from an object-oriented point of view, but this is dangerous. It can break the contract equals() and hashCode() (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 same Set can cause problems.

If you need different equivalence relationships, you should leave them outside your class. Equivalence allows you to do just that: you extract the equivalence logic (equals () / hashCode ()) by implementing equivalence and overriding the doHash() and doEquivalent() methods.

Then, when you want to use Collection based on one equivalence or another, you use Equivalence.wrap() . For example, you can emulate an IdentityHashSet by doing:

 Set<Equivalence.Wrapper<String>> identityHashSet = Sets.newHashSet(); String a1 = "a"; String a2 = new String("a"); String b = "b"; identityHashSet.add(Equivalences.identity().wrap(a1)); identityHashSet.add(Equivalences.identity().wrap(a2)); identityHashSet.add(Equivalences.identity().wrap(a3)); // identityHashSet contains "a", "a", and "b" // a standard HashSet would only contain "a" and "b" // while a1 and a2 are equal according to String.equals(), they are different instances. 

Of course, you can use ForwardingSet to automate the wrapping / unpacking of your elements.

Guava has more information on this issue .

+7
source

Source: https://habr.com/ru/post/1379177/


All Articles