为什么第3个对象没有被添加到树集中,虽然它是不同的?
import java.util.*;
class Student implements Comparable<Student>{
public String fn,ln;
public Student(String fn,String ln){
this.fn=fn;
this.ln=ln;
}
//overiding equals
public boolean equals(Object o) {
if (!(o instanceof Student))
return false;
Student s=(Student) o;
if(this==s)
return true;
if(this.fn.equals(s.fn) && this.ln.equals(s.ln))
return true;
return false;
}
//overiding hashcode
public int hashCode() {
return fn.hashCode()+ln.hashCode();
}
//overiding compareTo
public int compareTo(Student o) {
return this.fn.compareTo(o.fn);
}
}
public class Practice {
public static void main(String[] args) {
Student st1=new Student("Girish","J");
Student st2=new Student("Master","M");
Student st3=new Student("Girish","Jay");
Set S=new TreeSet();
//adding 3 different student objects
System.out.println(S.add(st1));
System.out.println(S.add(st2));
System.out.println(S.add(st3));
Iterator sitr=S.iterator();
while(sitr.hasNext())
{
Student stu=(Student) sitr.next();
System.out.println(stu.fn+" "+stu.ln);
}
}
}
输出:
true
true
false
Girish J
Master M
答案 0 :(得分:11)
您的比较器功能仅使用fn
:
public int compareTo(Student o) {
return this.fn.compareTo(o.fn);
}
TreeSet
仅使用排序比较 - 它不使用hashCode()
和equals()
。
通过此比较,st1
和st3
相等(s1.compareTo(s3)
将返回0)因此st3
未添加到集合中。
如果您想保持这种区别,您应该比较fn
,然后在ln
值相同的情况下使用fn
:
public int compareTo(Student o) {
int fnResult = this.fn.compareTo(o.fn);
return fnResult == 0 ? ln.compareTo(o.ln) : fnResult;
}
答案 1 :(得分:2)
您的观察结果是正确的,TreeSet不使用.equals和.hashcode进行比较。
来自javadocs:
This is so because the Set interface is defined in terms of the equals operation, but a
TreeSet instance performs all element comparisons using its compareTo (or compare) method,
so two elements that are deemed equal by this method are, from the standpoint of the set,
equal.
基本上,他们说对于TreeSet,相等性不是通过.equals确定的,而是通过Comparable接口上的.compareTo确定的。请注意.compareTo应始终与.equals一致,这意味着如果a.equals(b),则a.compareTo(b)== 0。
这与TreeSet是SortedSet的实现这一事实有关。因此,它需要.compareTo才能确定顺序,因为.equals在这种情况下是不够的。
PS:如果你不想实现Comparable(有时你不能,因为你可能不总是控制objets的代码),你总是可以将Comparator传递给TreeSet构造函数。
答案 2 :(得分:0)
您的比较仅使用fn
值...
public int compareTo(Student o) {
return this.fn.compareTo(o.fn);
}
第3个Student
失败,因为第一个名称与第1个Student
相同
您需要调整代码以比较fn
和ln
值......
public int compareTo(Student o) {
int firstNameComparison = this.fn.compareTo(o.fn);
if (firstnameComparison != 0){
// the first names are different
return firstNameComparison;
}
else {
// the first names are the same, so compare the last name
return this.ln.compareTo(o.ln);
}
}
此代码首先比较fn
值。如果它们相同,则会比较ln
值。