假设我正在构建一个对象的TreeSet
,其排序仅依赖于一个值.
我做不到
TreeSet<Foo> tree = new TreeSet<>(Comparator.comparingInt(Foo::getX));
因为如果我用相同的x
添加两个不同的Foo
对象,则其中一个将替换另一个(即,如果我添加tree.add(foo1)
和tree.add(foo2)
,tree.size()
将是1
而不是2
).
我可以比较Foo
的每个字段,但我希望Foo
的两个实例被认为是不同的,即使每个字段都是相同的.
一种"几乎奏效"的解决方案是
TreeSet<Foo> tree = new TreeSet<>(Comparator.comparingInt(Foo::getX).thenComparing(Foo::hashCode));
但当存在散列冲突时,这将失败.
In summary,我正在寻找类似的东西
TreeSet<Foo> tree = new TreeSet<>(Comparator.comparingInt(Foo::getX).thenComparing(Foo::getInternalAddress));
但当然,我们无法使用这种方法.
变通办法
我知道有一些变通办法:
- 如果我不关心对象本身,而只关心树中有多少个对象,我可以使用多集
TreeMap<Foo, Integer>
(并比较所有字段),从而得出特定x
有多少个Foo
- 如果我确实关心对象(我正在进行引用相等性判断),我可以使用不同的多集
TreeMap<Foo, List<Foo>>
(或键为x
的TreeMap<Integer, List<Foo>>
).但是,如果只有很少的"重复"foo,这是对所有单例列表所占用空间的浪费.
因此,虽然我知道有TreeMap
分的变通办法,但我仍然在想,是否有办法只用TreeSet
分就可以做到这一点.