compareto返回0时的java理解树集
我创建了一个学生类,如下所示:
public class Student implements Comparable<Student> {
private String firstName;
private String lastName;
public Student(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
// Getters & Setters follow here...
@Override
public int compareTo(Student student) {
int hash = this.firstName.compareTo(student.firstName);
return hash;
}
@Override
public String toString() {
return "Student [firstName=" + firstName + ", lastName=" + lastName
+ "]";
}
}
这是我的测试类,我只是在树集中添加元素:
public class SortedSetExample1 {
public static void main(String[] args) {
SortedSet<Student> set = new TreeSet<Student>();
set.add(new Student("A1","A2"));
set.add(new Student("B1","B2"));
set.add(new Student("A1","B2"));
set.add(new Student("A2","B2"));
System.out.println(set);
}
}
根据我的程序,输出为:
[Student [firstName=A1, lastName=A2], Student [firstName=A2, lastName=B2], Student [firstName=B1, lastName=B2]]
在我的测试类中,我正在向TreeSet
添加Student
对象,而且我还没有覆盖hashCode
&equals
方法。所以我希望TreeSet
将包含所有4个对象,但我也可以看到它包含3个对象。你能解释一下为什么new Student("A1","B2")
不是我的TreeSet
的一部分吗
同样根据这里的Java docs for TreeSet,它说:
Adds the specified element to this set if it is not already present. More formally, adds the specified element e to this set if the set contains no element e2 such that (e==null ? e2==null : e.equals(e2)). If this set already contains the element, the call leaves the set unchanged and returns false.
既然我没有重写equals
方法,那么为什么集合没有全部四个元素呢
# 1 楼答案
虽然这个问题已经很老了,但这里有一个非常重要的一点需要理解,大多数人在实现时忽略了这一点
TreeSet
不会将新元素与Set
中的所有现有元素进行比较。它使用二进制搜索技术。因此,如果您的输入元素等于一个现有元素(根据compareTo
契约),并且位于tree
的左侧,并且您的compareTo
方法的实现方式是强制新元素位于tree
的右侧,您的TreeSet
不会拒绝新元素,即使新元素中已经存在相同的元素(根据compareTo
合同)。让我们看看下面这个简单的例子我需要对属性为
key
和priority
的Item
进行排序输出:
但是,如果交换
line 1
和line 2
代码,输出将更改如下# 2 楼答案
由于在compareTo方法中只比较了名字,所以需要
当compareTo返回0时,treeSet假定其重复
# 3 楼答案
你的树集键值是“A1”,“B1”,“A1”,“A2”。即使你不重写等号和哈希代码,但“A1”的默认哈希代码将是相同的,因此树集将把这个密钥视为重复密钥,这样你就不能进入“A1”、“B2”
# 4 楼答案
这是因为
TreeSet
使用compareTo
(或Comparator.compare
)来测试两个元素是否相等。医生是这么说的# 5 楼答案
正如java.util.TreeSet所说:
感谢@Jon Skeet