Java HashSet with a custom equality criteria?

hashset, java, set

Solution

Nope, you've found exactly the solution you're supposed to use.

Even for `TreeSet`, it's frowned upon to use comparison criteria that aren't compatible with `equals`:

Note that the ordering maintained by a sorted set (whether or not an explicit comparator is provided) must be consistent with equals if the sorted set is to correctly implement the Set interface.

I don't know about Apache Commons, but Guava specifically rejected requests for this sort of thing, although you can achieve what you want using Guava Equivalence:

Equivalence<T> equivalence = new Equivalence<T>() {
    @Override
    protected boolean doEquivalent(T a, T b) {
        return CustomComparator.equals(a, b);
    }

    @Override
    protected int doHash(T item) {
        return CustomHashCodeGenerator.hashCode(item);
    }
};
List<T> items = getItems();
Set<Equivalence.Wrapper<T>> setWithWrappedObjects = items.stream()
    .map(item -> equivalence.wrap(item))
    .collect(Collectors.toSet());

Problem

I was looking for something akin to the Java TreeSet's ability to receive a custom comparator at instantiation time, so I needed not to use the object's default equality (and hash code) criteria. The closest I could come up with was to wrap my objects in a private custom class, but that seems hacky :( This ends up being a kind of recurring theme when programming, so I was wondering if there's something already available for us to use. Maybe in the commons libraries? Thanks

Original source

Related problems