对象从 Java TreeSet 中消失

kon*_*las 2 java

我有一个类,我想将其放入 a 中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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这个想法显然是为了按TreeSet优先级对对象进行排序,使我能够按顺序遍历侦听器。但是,我发现,由于某种原因,我无法PacketListener向设置的对象添加第二个对象。添加两个不同的PacketListener对象后,集合的大小仍为 1。

我不应该使用吗TreeSet

Joh*_*ger 7

API 文档TreeSet包含以下重要信息:

请注意,如果要正确实现接口,集合维护的顺序(无论是否提供显式比较器)必须与 equals 一致Set。[...] 之所以如此,是因为Set接口是根据equals操作定义的,但TreeSet实例使用其compareTo(or compare) 方法执行所有元素比较,因此从实例的角度来看,该方法认为两个元素相等设,相等。

换句话说, aTreeSet可以容纳类的多个实例PacketListener,但前提是每个实例都具有与其他所有实例不同的优先级,以便对于每对元素AB,其中一个恰好成立:要么A == B要么A.compareTo(B) != 0

如果必须PacketListener在同一个集合中容纳具有相同优先级的多个实例,那么您需要不同类型的集合。 对于使用从 继承的和方法HashSet的类来说非常好,只要这确实是所需的实例相等性。如果您想要对迭代顺序进行某种保证,或者如果您想按优先级排序但愿意使用不同的机制来避免重复,您也可以考虑 a 。equals()hashCode()ObjectLinkedHashSetPriorityQueue