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,或者我应该去一个简单的列表? 在某种程度上,我有独特的项目,列表也不是很完美。
有什么想法吗?
答案 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.