我正在尝试使用TreeSet创建二进制搜索树。我知道根据定义,一个集合不包含任何重复的条目。但是,我确信如果我创建自己的比较器,我可以允许TreeSet接受重复的条目。我这样做了:
public class A3BSTree <E> implements Tree <E> {
private TreeSet<E> tree;
private LinkedList<E> arr1;
private MyComparator comp;
public A3BSTree(){
tree = new TreeSet<>(comp);
}
...
...
...
private class MyComparator implements Comparator<E> {
@SuppressWarnings("unchecked")
@Override
public int compare(E e1, E e2) {
if (((A3BSTree<E>.MyComparator) e1).compareTo(e2) < 0) {
return -1;
}
else if (e1.equals(e2)) {
return 0;
}
else {
return 1;
}
}
public int compareTo(E e) {
return this.compareTo(e);
}
}
}
我不想要答案,我只需要解释为什么TreeSet仍然不会重复。我只需要朝着正确的方向转向。可能问题是我无法使用泛型创建比较器吗?
答案 0 :(得分:1)
java.util.TreeSet add()方法
java.util.TreeSet 类使用add方法将元素添加到Set中。此方法不允许重复。它使用Javadoc中提到的 equals()方法检测重复项。
public boolean add(E e) 如果指定的元素尚不存在,则将其添加到此集合中。更正式地,如果集合不包含元素e2,则将指定的元素e添加到该集合中(e == null?e2 == null:e.equals(e2))。如果此set已包含该元素,则调用将保持set不变并返回false。
目前的比较实施
根据您的 Comparator 实现,您希望equals方法识别重复项(可能您已覆盖它?)。
} else if (e1.equals(e2)) {
return 0;
}
如果是这种情况,我相信TreeSet的行为在拒绝基于 equals()方法的重复项时是正确的。
另一方面,可能最好使用Comparable方法而不是Comparator,因为它允许对象与其自己的实例相比较(差异为explained here)。