如何排除TreeSet.contains上的某些字段,但在所有字段上排序

时间:2014-12-11 20:05:11

标签: 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,或者我应该去一个简单的列表? 在某种程度上,我有独特的项目,列表也不是很完美。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

你可以改变,

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()将为您执行空检查。

答案 1 :(得分:0)

使用比较器来找到相等。

基于哈希的集合仅使用equals和hashcode进行相等。

但是像使用比较器的树一样收集平等。

如果两个对象相等,则compare方法应返回true,反之亦然。

set.contains(new A("a", 2)) its false because compare method wont return true`set.contains(new A("a", 1))` will return true because that method will return true.