2

为什么第三个对象没有被添加到这里的树集中,尽管它是一个不同的对象?

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
4

3 回答 3

11

您的比较器功能仅使用fn

public int compareTo(Student o) {
    return this.fn.compareTo(o.fn);
}

TreeSet 使用排序比较 - 它不使用hashCode()and equals()

通过这种比较,st1st3相等(s1.compareTo(s3)将返回 0)因此st3不会添加到集合中。

如果您想保持区别,您可能应该比较fn,然后lnfn值相同时使用:

public int compareTo(Student o) {
    int fnResult = this.fn.compareTo(o.fn);
    return fnResult == 0 ? ln.compareTo(o.ln) : fnResult;
}
于 2012-06-18T11:55:47.400 回答
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 (有时你不能,因为你可能并不总是控制对象的代码),你总是可以将 Comparator 传递给 TreeSet 构造函数。

于 2012-06-18T12:05:27.113 回答
0

您的比较仅使用该fn值...

public int compareTo(Student o) {
    return this.fn.compareTo(o.fn);
}

第三个失败,Student因为名字与第一个相同Student

您需要调整代码以比较fnln值...

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值。

于 2012-06-18T11:57:04.717 回答