Scala - использовать различные сравнения равенства / хэширования для одного и того же типа
Таким образом, в.NET вы можете определить реализации IEqualityComparer
и передать их конструктору Dictionary
или же HashSet
, В противном случае коллекции будут смотреть на Equals
а также GetHashCode
методы.
Это очень полезно, когда у вас есть несколько способов сравнения объектов. Например, вы можете посмотреть Person
по первичному ключу, доменному имени, адресу электронной почты и т. д.
Есть ли идиома в Java и Scala для достижения одного и того же? Я думаю, что было что-то проще, чем создать несколько подклассов, чтобы просто переопределить hashCode
а также equals
,
1 ответ
Библиотека Google Guava Java предоставляетEquivalence
класс для реализации пользовательских отношений эквивалентности. Он не поддерживает изменение семантики эквивалентности
Set
или же
Map
напрямую, но его можно использовать для обертывания элементов, чтобы их можно было сравнивать с использованием пользовательского отношения эквивалентности.
Person person1 = Person.withEmail("john.doe@example.com");
Person person2 = Person.withEmail("jane.doe@example.com");
Person person3 = Person.withEmail("john.doe@example.com");
Equivalence<Person> emailEquivalence = Equivalence.equals().onResultOf(Person::getEmail);
Set<Equivalence.Wrapper<Person>> set =
Set.of(emailEquivalence.wrap(person1), emailEquivalence.wrap(person2));
assert set.contains(emailEquivalence.wrap(person3));
Map<Equivalence.Wrapper<Person>, Integer> map =
Map.of(emailEquivalence.wrap(person1), 1, emailEquivalence.wrap(person2), 2);
assert map.get(emailEquivalence.wrap(person3)) == 1;