java - 如何排除 TreeSet.contains 上的某些字段但对所有字段进行排序

标签 java

TreeSet 有一些问题,或者我只是意识到它没有按我的预期工作。 当我检查值是否已存在时,我需要排除一些字段,但在排序时它应该使用所有字段。 看起来TreeSet.contains()使用compare或compareTo(比较器,可比较)而不是equals()。

这是一些示例:

import java.util.Comparator;
import java.util.TreeSet;

public class sorter {

    static class A {
        String name;
        int counter;

        public A(String a, int counter) {
            this.name = a;
            this.counter = counter;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (obj == null) return false;
            if (getClass() != obj.getClass()) return false;
            A other = (A)obj;
            if (name == null) {
                if (other.name != null) return false;
            } else if (!name.equals(other.name)) return false;
            return true;
        }
    }

    public static class MyComparator implements Comparator<A> {
        @Override
        public int compare(A a, A b) {
            int c = b.counter - a.counter;
            if (c == 0) {
                return a.name.compareTo(b.name);
            };
            return c;
        }
    }

    public static void main(String[] args) {
        TreeSet<A> set = new TreeSet<>(new MyComparator());
        set.add(new A("a", 1));

        if (set.contains(new A("a", 2))) {
            System.out.println("'a' already exists, do count + count");
        }
    }

感觉我在这里违反了一些法律,应该以某种方式重新设计它? 是否可以实现我尝试使用 TreeSet 做的事情,或者我应该选择一个简单的列表? 在某种程度上,我有独特的元素,但列表也感觉不完美。

有什么想法吗?

最佳答案

你可以改变,

public int compare(A a, A b) {
    int c = b.counter - a.counter;
    if (c == 0) {
        return a.name.compareTo(b.name);
    };
    return c;
}

成为

public int compare(A a, A b) {
    if (Objects.equals(a, b))
       return 0;
    int c = b.counter - a.counter;
    if (c == 0) {
        return a.name.compareTo(b.name);
    };
    return c;
}

这样,如果它们在您的平等意义上“相等”,TreeSet 将排除它们。否则,您可以按照自己的意愿排序。请注意,Objects.equals() 将为您执行 null 检查。

关于java - 如何排除 TreeSet.contains 上的某些字段但对所有字段进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27431454/

相关文章:

java - 源代码是否应该以 UTF-8 格式保存

java - 衡量 Java 应用程序的性能

java - Logback 控制台日志记录故障安全

java - 读取 XML 文件行并将它们作为 java 中的字符串读入。

java - hibernate 获取模式加入不工作

java - 如何在 Selenium 中切换

java - 我可以在 EJB 3.2 中获得类似实体 bean 的东西吗?

java - 从 Oracle 触发器启动 Java Web 应用程序中的流程

java - 如何通过 SMPP 协议(protocol)连接到 SMSC 服务器?

java - 让Gson按照一定的顺序序列化Set