Hack:java.util.TreeSet中的重复项?

Hack:java.util.TreeSet中的重复项?,java,data-structures,Java,Data Structures,我有一节简单的课 public class A { int val; public A(int val) {this.val = val;} } 我将A实例存储在java.util.TreeSet中,如下所示: SortedSet<A> ss = new TreeSet<A>(new Comparator<A>() { @Override public int compare(A o1, A o2) { ret

我有一节简单的课

public class A {
    int val;
    public A(int val) {this.val = val;}
}
我将
A
实例存储在
java.util.TreeSet
中,如下所示:

SortedSet<A> ss = new TreeSet<A>(new Comparator<A>() {
    @Override
    public int compare(A o1, A o2) {
        return Integer.compare(o1.val, o2.val);
    }
});
或者我应该切换到另一个数据结构?(如果存在比R-B树更好的替代)

哦,天哪,我知道它很酷,这里的每个人都喜欢它


结论:使用。

我想您希望不同的A实例在您的集合中共存,即使它们共享相同的val,并且不要多次添加相同的A实例

A a = new A(1);
A b = new A(1);
A c = new A(2);
A d = c;
ss.add(a);
ss.add(b);
ss.add(c);
ss.add(d);
然后,您希望
ss
包含三个实例:两个1值和一个2值(因为a和b是不同的实例,c和d包含相同的实例)。这就是您的代码将要做的(如果您不从对象重写hashCode()方法)


只有一个改进:
o1.hashCode()-o2.hashCode()
可能会产生算术溢出,最好对该部分也使用
Integer.compare()
。例如,2000000000-(-2000000000)将给出负结果,尽管第一个数字更大。这将导致所有基于比较器的结构行为异常。

这就是我想说的。。。为什么不使用
队列
,尤其是文档中所述的
优先队列

实现说明:此实现为排队和退队方法提供了O(log(n))时间:offer、poll、remove和add;移除(对象)和包含(对象)方法的线性时间;以及检索方法、peek和大小的固定时间

PriorityQueue
vs
Tree
的区别还在于,第一个更轻,因为它使用了
二进制堆
,而不是
红黑树
;因此,
PriorityQueue
将使用一个数组来存储不难理解的数据


还请注意,如果您经常使用高优先级任务填充
PriorityQueue
,则低优先级任务在处理之前可能会等待很长时间

@dehasi,这有什么帮助?如果值相等,hashCode和equals应该与well@Anon,我只是误解了这个问题。不可能将相同的值放入一个集合。只是因为。。设置集合只包含不同的值。也许
Guava
中的
Multiset
会有帮助。@dehasi在
java.util.TreeMap
源代码中查看
final Entry getEntry(Object key)
方法。。。我很确定
equals
hashCode
对于
HashMap
HashSet
Map
Set
实现方面是至关重要的。@CedricSun您看到的复杂性是什么,即“快速”是什么此处:快速插入快速删除快速查询具有最小val@CedricSun您需要查询最小值,您需要一个堆,而不是一个集合,试试看,是的……自从我上次做关于数据结构和算法的练习以来,已经有很长一段时间了,而且是第一次用Java。我实际上是在解决问题。希望这篇文章能帮助那些有同样困惑的人:)溢出不是OP方法的唯一问题-还有哈希冲突(如果集合的大小足够大,插入和删除的性能就很重要)。@Hulk:你说得对。有一个方面,我对32位Java的体验对64位Java不再有效:-(.对于32位Java,标准JRE的Object.hashCode()返回内部地址(“这通常通过将对象的内部地址转换为整数[…]),结果是Object.hashCode()从未发生冲突,因为地址和整数的大小相同。但对于64位地址和32位整数,这不再可能,甚至Object.hashCode()也可能会产生冲突。
A a = new A(1);
A b = new A(1);
A c = new A(2);
A d = c;
ss.add(a);
ss.add(b);
ss.add(c);
ss.add(d);