TreeSet示例

时间:2012-06-18 11:50:44

标签: java string-comparison treeset

为什么第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

3 个答案:

答案 0 :(得分:11)

您的比较器功能仅使用fn

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

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

通过此比较,st1st3相等(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相同

您需要调整代码以比较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值。