Let's say I am building a TreeSet
of an object for which the ordering depends on only one value.
I cannot do
TreeSet<Foo> tree = new TreeSet<>(Comparator.comparingInt(Foo::getX));
because if I add two different Foo
objects with the same x
then one would replace the other (i.e. if I do tree.add(foo1)
and tree.add(foo2)
, tree.size()
will be 1
instead of 2
).
I could compare every field of Foo
, but I would like two instances of Foo
to be considered distinct, even if every field is the same.
One solution that "almost works" would be
TreeSet<Foo> tree = new TreeSet<>(Comparator.comparingInt(Foo::getX).thenComparing(Foo::hashCode));
But this would fail when there is a hash collision.
In summary, I am looking to something similar to
TreeSet<Foo> tree = new TreeSet<>(Comparator.comparingInt(Foo::getX).thenComparing(Foo::getInternalAddress));
But of course we don't have access to such method.
Workarounds
I know there are workarounds:
- if I don't care about the objects themselves but just how many are in the tree, I can use a multiset
TreeMap<Foo, Integer>
(and comparing all the fields) that give me how manyFoo
s for a specificx
- if I do care about the objects (I am making reference equality checks) I can use a different multiset
TreeMap<Foo, List<Foo>>
(orTreeMap<Integer, List<Foo>>
with the key beingx
). But if there are very few "duplicated" foos, this is a waste of space taken by all the singleton lists.
So while I know there are workarounds with a TreeMap
, I still wonder if there is a way to do that with just a TreeSet
.