2016-06-22 7 views
1

オブジェクトをツリーセットに追加しようとしていますが、オブジェクトがすべて追加されていません。オブジェクトを追加していないJava TreeSet

class Fruits 
{ 
    String name ; 
    int weight; 
    int price; 

    Fruits(String n, int w, int p) 
    { 
     this.name=n; 
     this.weight=w; 
     this.price =p; 
    } 

    @Override 
    public int hashCode() { 
     System.out.println("hashcode called"); 
     int prime =31; 
     int result =1; 
     result = prime*result +(this.name.hashCode()+this.price+this.weight); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     System.out.println("Equals called"); 
     if(null!=obj) 
     { 
      Fruits f= (Fruits) obj; 
      if(this.name.equals(f.name) && this.price==f.price && this.weight == f.price) 
      { 
       return true; 
      } 
     } 
     return false; 
    } 
} 

class FruitsComparator implements Comparator<Fruits> 
{ 
    //Order by Name, then quanity and then Price 
    @Override 
    public int compare(Fruits f1, Fruits f2) 
    { 
     if(f1.name.equals(f2.name) && f1.weight == f2.weight && f1.price == f2.price) 
     { 
      System.out.println(1); 
      return 0; 
     } 
     else if(f1.name.equals(f2.name) && f1.weight==f2.weight && f1.price < f2.price) 
     { 
      System.out.println(2); 
      return -1; 
     } 
     else if (f1.name.equals(f2.name) && f1.weight==f2.weight && f1.price > f2.price) 
     { 
      System.out.println(3); 
      return 1; 
     } 
     else if (f1.name.equals(f2.name) && f1.weight<f2.weight && f1.price == f2.price) 
     { 
      System.out.println(4); 
      return -1; 
     } 
     else if (f1.name.equals(f2.name) && f1.weight>f2.weight && f1.price == f2.price) 
     { 
      System.out.println(5); 
      return 1; 
     } 
     else if (f1.name.compareTo(f2.name) <1 && f1.weight==f2.weight && f1.price == f2.price) 
     { 
      System.out.println(6); 
      return -1; 
     } 
     else if (f1.name.compareTo(f2.name) >1 && f1.weight==f2.weight && f1.price == f2.price) 
     { 
      System.out.println(7); 
      return 1; 
     } 
      return 0; 
    }  
} 

他のクラスのpublic static void main。

Fruits f1= new Fruits("Apple",1,3); 
Fruits f2= new Fruits("Apple",10,1); 
Fruits f3= new Fruits("Apple",15,2); 
Set<Fruits> sf = new TreeSet<Fruits>(new FruitsComparator()); 
sf.add(f1); 
sf.add(f2); 
sf.add(f3); 
System.out.println("--Fruits Example--"); 
for(Fruits f: sf) 
{ 
    System.out.println(f.name+"-"+f.weight+"-"+f.price); 
} 

私が手出力は次のようになります。

--Fruits Example-- 
Apple-1-3 

しかし、私は以下のように果物OBJSを持っているとき、私はちょうど同じすべてが、第三の要素を保ち すべてのオブジェクトを取得。 フルーツf1 =新しいフルーツ(「アップル」、1,3); フルーツf2 =新しいフルーツ( "アップル"、1,1); フルーツf3 =新しいフルーツ( "アップル"、1,2);出力は、このために取得

は、私は重量と価格の異なる要素を保つときに何とか私のオブジェクトは同じように扱われ

--Fruits Example-- 
Apple-1-1 
Apple-1-2 
Apple-1-3 

です。オブジェクトが同じように扱われる理由を私は理解できませんでした。助けてください。

+0

コピー・ペースト・エラー( 'f.price'は' f.weight'でなければなりません)としてクローズしてください。 – dasblinkenlight

+0

あなたのコンパイラの実装は、読めるように混乱します。また、 '.compareTo'の結果は0ではなく1と比較されるべきです。 –

答えて

1

主な問題は、常に2つのフィールドが等しいことと、1つだけが異なることを確認することです。 最後のelseでは、少なくとも2つのフィールドが異なる場合に起こります.0を返すと、これは等しいとみなされるため、この問題が発生します。

最初に名前で並べ替え、次に数量で、次に価格で並べ替えることは、4番目の条件から&& f1.price == f2.priceを削除し、最後の2つで&& f1.weight==f2.weightを削除することです。


Java 8スタイルを使用すると、この問題は完全に回避できます。

Set<Fruits> sf = new TreeSet<Fruits>(Comparator.comparing(Fruits::getName) 
    .thenComparing(Fruits::getWeight) 
    .thenComparing(Fruits::getPrice) 
    ); 

私はcodiva - online java compiler ideに作業コードを追加しました。私は、FruitsComparator.javaファイルにややクリーンな実装を追加しました。

0

あなたはクラスFruitsであなたのequals方法に誤りがあります。

if(this.name.equals(f.name) && this.price==f.price && this.weight == f.price) 

はされている必要があります。

if(this.name.equals(f.name) && this.price==f.price && this.weight == f.weight) 

(最後の部分に注意してください)。

+0

私はタイプミスを変更しましたが、それでも動作は変わりません。私はコンパレータクラスで私の比較を見直す必要があると信じています。ありがとう。 – GAK

+0

TreeSetとTreeMapは、とにかくequalsメソッドとhashCodeメソッドを使用しません。それらはHashSetとHashMapに使用されます。この質問のために、それらは無関係です。 正しい解決策について私の答えを見てください。修正はコンパレータにあります。 – JackDaniels

1

ツリー関連のコレクションは、equals()またはhashCode()を使用していません。それらはMapで再生されます。

の条件は0になり、果物は挿入されません。

最初にAppleがツリーが空であるために入ります。第2の&第3のアップルの結果はすべてifの条件でfalseになり、最終的に0に戻ります。最終的なreturnの前にSystem.out.println()を入れて確認してください。

あなたは価格で、最終的に、その後重量&によって、名前で最初の成果をソートしたい場合は、ここでそれをやって、よりコンパクトな方法です:

Comparatorで使用
@Override 
public int compare(Fruits f1, Fruits f2) { 
    if (f1.name.equals(f2.name)) { 
     if (f1.weight < f2.weight) { 
      return -1; 
     } else if (f1.weight > f2.weight) { 
      return 1; 
     } else { 
      if (f1.price < f2.price) { 
       return -1; 
      } else if (f1.price > f2.price) { 
       return 1; 
      } else { 
       return 0; 
      } 
     } 
    } else { 
     return f1.name.compareTo(f2.name); 
    } 
} 
+0

ありがとうございます。私はそれがどこにあるのかを信じています。しかし、なぜ私の比較方法で条件が満たされているのかわかりません。あなたが時間を見つけたら見てください。ありがとう。 – GAK

+0

あなたの条件のどれも満たされていません。 7行目の後に 'System.out.println(8)'を置き、完全な 'if'ブロックの後にこれを表示します。すべての 'if'条件では、' name'、 'weight'または' price'が/ '=='と等しくなりますが、3つのリンゴのどれも 'weight'や' price'はありません。 – Vineet

0

TreeSet、要素等価性はComparatorcompareメソッドによって決定され、そうでない場合はインターフェイスを実装する必要があるため、要素のcompareToメソッドを使用します。 hashcodeequalsのメソッドは、containsのメソッドequalsを使用して、要素が表示されているかどうかを確認するなど、インターフェイス自体でのみ使用されます。 hashcodeTreeSetが使用されているのではなく、HashSetによって使用されていますが、これはSetインターフェイスを実装するまったく別の方法です。したがって、あなたのコードではComparatorのオーバーライドしたcompareメソッドはこれらの要素を等しく扱うので、複数回挿入することはできません。 Javaチュートリアルで指摘しているガイドラインの1つはcompareメソッドはequalsメソッドに準拠する必要があります。つまり、equalsメソッドの場合に限り、compareメソッドで要素を同等に扱う必要があります。

equalsの方法では、私はあなたが意図したとは思わない2つの果物を比較するのにthis.weight == f.priceを使用しました。これにより、equalsメソッドがcompareメソッドと一貫しません。

参考までに、Java Object Orderingチュートリアルを参照してください。a question私は2日前に尋ねました。

関連する問題