2

別のオブジェクトなのに、なぜ 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
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 を使用しないという観察は正しいです。

javadoc から:

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名が 1 番目と同じであるため、3 番目は失敗します。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値を比較します。

于 2012-06-18T11:57:04.717 に答える