我有一个类,我想将其放入 TreeSet
中,它实现了 Comparable
以按优先级对它们进行排序。这是一小段:
public abstract class PacketListener implements Comparable<PacketListener> {
public enum ListenerPriority {
LOWEST, LOW, NORMAL, HIGH, HIGHEST
}
private final ListenerPriority priority; // Initialized in constructor
// ... class body ...
@Override
public final int compareTo(PacketListener o) {
return priority.compareTo(o.priority);
}
}
TreeSet
的想法显然是按优先级对对象进行排序,从而允许我按顺序循环访问监听器。但是,我发现,出于某种原因,我无法向 set 对象添加第二个 PacketListener
。添加两个不同的 PacketListener
对象后,集合的大小保持为 1。
我不应该使用 TreeSet
吗?
最佳答案
The API docs for TreeSet
包含以下重要信息:
Note that the ordering maintained by a set (whether or not an explicit comparator is provided) must be consistent with equals if it is to correctly implement the
Set
interface. [...] This is so because theSet
interface is defined in terms of theequals
operation, but aTreeSet
instance performs all element comparisons using itscompareTo
(orcompare
) method, so two elements that are deemed equal by this method are, from the standpoint of the set, equal.
换句话说,TreeSet
可以容纳您的 PacketListener
类的多个实例,但前提是每个实例都具有与其他所有实例不同的优先级,因此对于每对元素 A 和 B,恰好其中一个成立:A == B
或 A.compareTo(B) != 0
。
如果您必须在同一集合中容纳多个具有相同优先级的 PacketListener
实例,那么您需要不同类型的集合。 HashSet
非常适合使用从 Object
继承的 equals()
和 hashCode()
方法的类,前提是这确实是实例平等的理想意义。如果你想要某种关于迭代顺序的保证,你也可以考虑使用 LinkedHashSet
,或者如果你想按优先级排序但你愿意使用不同的方式,你可以考虑使用 PriorityQueue
避免重复的机制。
关于java - 从 Java TreeSet 中消失的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37396972/