Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

customizable equals/hashCode for Maps/Collections #188

Closed
gissuebot opened this issue Oct 31, 2014 · 12 comments
Closed

customizable equals/hashCode for Maps/Collections #188

gissuebot opened this issue Oct 31, 2014 · 12 comments
Labels
status=will-not-fix type=enhancement Make an existing feature better
Milestone

Comments

@gissuebot
Copy link

Original issue created by zeitlinger on 2009-06-10 at 07:54 AM


TreeMap has the advantage that one can specify which objects are equal
using a Comparator.

It would be useful to be able to specify this for HashMaps and generally
all collections that work with equals/hash

public interface Equalator/Equator<T> {
  boolean equals(T left, T right);
}
public interface Hasher<T> extends Equalator<T> {
  int hashCode(T t);
}

Apache collections allows you to override AbstractHashedMap.hash/isEqualKey

  • which is similar.
@gissuebot
Copy link
Author

Original comment posted by kevinb9n on 2009-06-10 at 03:43 PM


We have an experimental version of this internally. It has a single interface with
both methods, called Equivalence. We have not yet found it to be highly useful.
It's the kind of thing that does have legitimate uses, but more people use it badly
than well. Still, this could eventually work its way out.

@gissuebot
Copy link
Author

Original comment posted by zeitlinger on 2009-06-11 at 07:25 AM


A discussion on Artima brought this up (in the discussion).
Basically, it's hard to write an equals method that is both correct and useful.
Therefore, it's easier to be able to provide one where needed.

http://www.artima.com/lejava/articles/equality.html

@gissuebot
Copy link
Author

Original comment posted by Ben.Lings on 2009-06-17 at 11:54 AM


Dot Net has something similar:

http://msdn.microsoft.com/en-us/library/ms132151.aspx (IEqualityComparer<T>)

and its default implementation, EqualityComparer<T>.Default

http://msdn.microsoft.com/en-us/library/ms224763.aspx

The default implementation will use IEquatable<T>.Equals(T other) if T implements
IEquatable, otherwise it will use Object.Equals(Object other).

All Dot Net collection implementations that use a hashcode (Dictionary<TKey, TValue>
and HashSet<T>) take an optional constructor argument allowing an IEqualityComparer
to be specified (in the same way that SortedSet and SortedMap implementations in Java
can take a Comparator as a constructor argument).

Having used the Dot Net version, I would suggest changing the names of the methods so
that they aren't overloads of Object.equals and Object.hashCode . Maybe
Equivalence<T>.areEqual(T, T) and Equivalence<T>.hashCodeFor(T) ?

@gissuebot
Copy link
Author

Original comment posted by ray.a.conner on 2009-08-03 at 08:03 PM


Implementations need not be exposed, so it wouldn't be too much bloat. I think you
just need:

  • the Equivalence interface
  • static factory methods taking an Equivalence and a backing Collection/Map

If you want, you can add a constant Equivalence implementation using reference
equality, defined as a singleton constant in the Equivalence interface so as not to
expose that class either.

@gissuebot
Copy link
Author

Original comment posted by stephen.kestle on 2009-08-10 at 04:27 AM


I had a conversation here about this a year ago (about Equators - either mailing list
or issue), but I can't find it.

I created an issue for this at apache commons collections: https://issues.apache.org/jira/browse/COLLECTIONS-242
The checked in version is at http://svn.apache.org/viewvc/commons/proper/collections/branches/collections_jdk5_bra
nch/src/java/org/apache/commons/collections/functors/Equator.java?
revision=643590&pathrev=643590

As in that ticket, there are times you want to equate objects under a different
mechanism, and a number of new possibilities emerge - one of my highest use ones
being an EquatableSet, which allows a "T get(Object equals)" type method, where an
object that is equivalent under the Equator is able to be retrieved in a map style
fashion.

@gissuebot
Copy link
Author

Original comment posted by kevinb9n on 2009-08-13 at 02:49 PM


(No comment entered for this change.)


Status: Accepted
Labels: post-1.0

@gissuebot
Copy link
Author

Original comment posted by kevinb9n on 2009-09-17 at 05:45 PM


(No comment entered for this change.)


Labels: -post-1.0, Milestone-Post1.0

@gissuebot
Copy link
Author

Original comment posted by kevinb9n on 2009-09-17 at 05:57 PM


(No comment entered for this change.)


Labels: Type-Enhancement

@gissuebot
Copy link
Author

Original comment posted by kevinb@google.com on 2010-04-23 at 08:40 PM


At best we will consider this for MapMaker -- bug 337. I'm extremely reluctant to
carry it beyond this (or even to go that far, to be honest). Collections with
nonstandard equivalence are spec violations that play badly with other kids, sometimes
causing bugs in extremely nonobvious ways.


Status: WontFix

@gissuebot
Copy link
Author

Original comment posted by earwin on 2010-04-23 at 09:00 PM


But there's a whole bunch of collections with Comparator-based equivalence which are
perfectly fine. What makes Equivalence-based equivalence a violation?

@gissuebot
Copy link
Author

Original comment posted by kevinb@google.com on 2010-04-23 at 09:16 PM


Such comparators should be consistent with equals():

"Note that the ordering maintained by a sorted map (whether or not an explicit
comparator is provided) must be consistent with equals if this sorted map is to
correctly implement the Map interface. (See Comparable or Comparator for a precise
definition of consistent with equals.)"

So that satisfies me as well.

I'm just saying, to the extent you want to make this case, focus on making it for
MapMaker right now, because that's the most likely of any collection that we would
support this for.

@gissuebot
Copy link
Author

Original comment posted by stephen.kestle on 2010-10-12 at 09:54 PM


I guess our spec is rather different from .Net, which has had this since version 2: http://msdn.microsoft.com/en-us/library/system.collections.iequalitycomparer.aspx.

I comment again, as this again causes us significant pain as I'm supporting a project which has at least 3 ways of equating each different object type.

I guess overall I'm thankful for google's spec-api approach after the headaches I had with apache-collection's "helpers"

@cgdecker cgdecker modified the milestone: Post-1.0 Nov 1, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status=will-not-fix type=enhancement Make an existing feature better
Projects
None yet
Development

No branches or pull requests

2 participants