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/