java - 从 Java TreeSet 中消失的对象

标签 java

我有一个类,我想将其放入 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 the Set interface is defined in terms of the equals operation, but a TreeSet instance performs all element comparisons using its compareTo (or compare) method, so two elements that are deemed equal by this method are, from the standpoint of the set, equal.

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

如果您必须在同一集合中容纳多个具有相同优先级的 PacketListener 实例,那么您需要不同类型的集合。 HashSet 非常适合使用从 Object 继承的 equals()hashCode() 方法的类,前提是这确实是实例平等的理想意义。如果你想要某种关于迭代顺序的保证,你也可以考虑使用 LinkedHashSet,或者如果你想按优先级排序但你愿意使用不同的方式,你可以考虑使用 PriorityQueue避免重复的机制。

关于java - 从 Java TreeSet 中消失的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37396972/

相关文章:

java - 使用线程进行堆排序

java - 使用 JRE 或 JDK 编译的 Eclipse

java - 未执行自定义约束 validator 注释

java - 如何从 Android 中的不同 Activity 调用方法

java - Java中如何从父类(super class)调用子类方法?

java - 批处理文件 '%' 在设置 java 属性时放置额外的空间

Java - 使用 Netbeans 隐藏/显示外部 jPanel?

Java 修改控制台输出以进行调试

java - 匹配字符串中的 css margin 属性

java - 为什么这个 FetchType.LAZY 被忽略并且所有实体都在查询中获取?