我有一个简单的课程
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);
}
});
以后才能找到具有相同A
值的val
个实例无法在TreeSet
中共存。
我需要TreeSet
,因为我想:
val
由于相等性完全取决于compare()
的返回值0以及我们如何实现它,是否有一种黑客方式允许具有相同值val
的实例在TreeSet
中共存}?
我的解决方法是在val
相等的情况下返回稳定的非零值,但事实证明它不稳定。
SortedSet<ListNode> ss = new TreeSet<ListNode>(new Comparator<ListNode>() {
@Override
public int compare(ListNode o1, ListNode o2) {
if (o1.val != o2.val) return Integer.compare(o1.val, o2.val);
return o1.hashCode() - o2.hashCode(); // not to return 0
}
});
或者我应该切换到另一个数据结构? (如果存在一些比R-B树更好的替代品)
而且,哦,Geez,我知道modeling the mathematical set abstraction很酷,所有人都喜欢它。
结论:使用priority queue。
答案 0 :(得分:3)
这就是我想说的......为什么不使用文档所说的Queue
,特别是PriorityQueue
:
实施说明:此实现为入队和出队方法提供O(log(n))时间:offer,poll,remove和add; remove(Object)和contains(Object)方法的线性时间;检索方法,窥视和大小的恒定时间。
PriorityQueue
vs Tree
中的差异也是第一个更轻,因为它使用binary heap
而不是red-black tree
;因此PriorityQueue
将使用数组来存储其难以理解的数据。
另请注意,如果您经常使用高优先级任务填充PriorityQueue
- 您的低优先级任务可能会在处理之前等待很长时间。
答案 1 :(得分:-2)
我想您希望不同的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包含相同的实例)。这就是你的代码将要做的事情(如果你不覆盖Object的hashCode()方法)。
只有一项改进:o1.hashCode() - o2.hashCode()
可能会产生算术溢出,对该部分也更好地使用Integer.compare()
。例如。尽管第一个数字更大,但2000000000 - (-2000000000)将给出否定结果。这将导致所有基于比较器的结构表现得异常。