简体   繁体   English

hack:在java.util.TreeSet中重复吗?

[英]Hack: Duplicates in java.util.TreeSet?

I have a simple class 我有一堂简单的课

public class A {
    int val;
    public A(int val) {this.val = val;}
}

I store A instances in a java.util.TreeSet like: 我将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);
    }
});

Only to find later that A instances with the same val values cannot coexist in TreeSet . 后来才发现,具有相同val值的A实例不能在TreeSet共存。

I need TreeSet because I want: 我需要TreeSet是因为我想要:

  • Quick Insertion 快速插入
  • Quick Removal 快速拆卸
  • Quick Query of Element with Minimum val 元素的快速查询与最低val

Since the equality completely depends on the return value 0 of compare() and how we implement it, is there a hacking way that allow instances with the same value of val to coexist in TreeSet ? 由于相等性完全取决于compare()的返回值0和我们如何实现,因此是否存在一种黑客方法,允许具有val相同值的实例共存于TreeSet

My workaround is to return a stable non-zero value if val are equal, but it proves to be unstable. 我的解决方法是,如果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
    }
});

Or should I just switch to another data structure? 还是我应该切换到另一个数据结构? (if there exists some substitute better than RB Tree) (如果存在比RB树更好的替代品)

And, Oh Geez, I know modeling the mathematical set abstraction is cool and everyone here loves it. 而且,哦,天哪,我知道对数学集合抽象进行建模很酷,这里的每个人都喜欢它。

Conclusion : use priority queue . 结论 :使用优先级队列

That's what I wanted to say... why not use a Queue and especially a PriorityQueue that the documentation says to have : 这就是我想说的...为什么不使用文档中规定的Queue尤其是PriorityQueue

Implementation note: this implementation provides O(log(n)) time for the enqueuing and dequeuing methods: offer, poll, remove and add; 实施说明:此实施为入队和出队方法提供O(log(n))时间:提供,轮询,删除和添加; linear time for the remove(Object) and contains(Object) methods; remove(Object)和contains(Object)方法的线性时间; and constant time for the retrieval methods, peek, and size. 以及检索方法,窥视和大小的固定时间。

The diff in PriorityQueue vs Tree is also that the first one is more light-weight as it uses a binary heap as opposed to red-black tree ; PriorityQueueTree的区别还在于,第一个比较轻巧,因为它使用binary heap而不是red-black tree so the PriorityQueue will use an array to store it's data that is not that hard to understand. 因此PriorityQueue将使用数组来存储不难理解的数据。

Also notice that if you populate your PriorityQueue often with high priority tasks - your low priority tasks could wait a lot of time before they are processed. 还要注意,如果您经常用高优先级任务填充PriorityQueue队列-低优先级任务可能要等待很长时间才能被处理。

I suppose you want different A instances to coexist in your set even if they share the same val, and not to add the same A instance more than once. 我想即使您共享相同的val,您也希望不同的A实例在您的集合中共存,并且不要多次添加同一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);

After that, you want ss to contain three instances: two 1 values and one 2 value (because a and b are different instances, c and d contain the same). 之后,您希望ss包含三个实例:两个1值和一个2值(因为a和b是不同的实例,c和d包含相同的实例)。 That is what your code will do (if you don't override the hashCode() method from Object). 这就是您的代码将要执行的操作(如果您不重写Object的hashCode()方法)。

Just one improvement: o1.hashCode() - o2.hashCode() might produce arithmetic overflow, better use Integer.compare() for that part, too. 只是一项改进: o1.hashCode() - o2.hashCode()可能会产生算术溢出,对于该部分,最好也使用Integer.compare() Eg 2000000000 - (-2000000000) will give a negative result although the first number is greater. 例如,尽管第一个数字更大,但2000000000-(-2000000000)将给出负结果。 And that will cause all Comparator-based structures to behave strangely. 这将导致所有基于Comparator的结构表现异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 GSON:使用java.util.TreeSet序列化对象 - GSON: Serialize object with java.util.TreeSet java.util.TreeSet的tailSet操作的时间复杂度是多少? - What is the time complexity of the tailSet operation of java.util.TreeSet? java.util.HashSet和java.util.TreeSet使用什么算法在其结构中存储唯一值? - What Algorithm is used by java.util.HashSet and java.util.TreeSet to store unique values in its structure? 是什么原因导致ClassCastException:java.util.TreeSet无法转换为java.lang.Comparable? - What causes the ClassCastException: java.util.TreeSet cannot be cast to java.lang.Comparable? 自定义包装的枚举类型不支持java.util.TreeSet集合类型 - java.util.TreeSet collection type not supported for custom wrapped enum type Java - 接受重复的TreeSet - Java - TreeSet accepting duplicates java:Comparator和Treeset删除重复项 - java: Comparator and Treeset to remove duplicates Java中的数据结构是否与TreeSet类似但允许重复? - Is there data structure in Java that is like TreeSet but allows duplicates? Java TreeSet 基于 object 属性删除重复项 - Java TreeSet remove duplicates based on object attribute Java:为什么我的HashSet和TreeSet包含重复项? - Java: Why does my HashSet and TreeSet contain duplicates?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM