2016-09-08 2 views
1

私はComparatorのJavaコレクションの機能の詳細を学ぶためのコードを書いています。私はそれぞれに3つの要素を持つ2つのセットを持っています。私は比較したい。 私は下に私のコードを掲示し、カウンタ変数の出力。誰も変数iがこの奇妙な出力を与える理由を説明できますか?私は流れを理解できませんでした。コンパイラのカウンタ変数の奇妙な出力

public class TestProductBundle { 
public static void main(String args[]) { 

    TestProductBundle productBundle = new TestProductBundle(); 

    Set<ClassA> hashSetA = new HashSet<ClassA>() { 
     { 
      add(new ClassA("name", 1, "desc")); 
      add(new ClassA("name", 2, "desc")); 
      add(new ClassA("name", 3, "desc")); 
     } 
    }; 

    Set<ClassA> hashSetB = new HashSet<ClassA>() { 
     { 
      add(new ClassA("name1", 2, "desc1"));  //"name" & "desc" are different than previous 
      add(new ClassA("name2", 1, "desc2")); 
      add(new ClassA("name3", 3, "desc3")); 
     } 
    }; 

    if (productBundle.compareCollection(hashSetA, hashSetB)) { 
     System.out.println("Equal set of tree"); 
    } else { 
     System.out.println("Unequal set of tree"); 
    } 
} 

@SuppressWarnings("serial") 
public boolean compareCollection(Set<ClassA> collection1, Set<ClassA> collection2) { 

    TreeSet<ClassA> treeSetA = new TreeSet<ClassA>(new CompareID()) { 
     { 
      addAll(collection1); 
     } 
    }; 

    TreeSet<ClassA> treeSetB = new TreeSet<ClassA>(new CompareID()) { 
     { 
      addAll(collection2); 
     } 
    }; 

    if (treeSetA.containsAll(treeSetB) && treeSetB.containsAll(treeSetA)) 
     return true; 
    else 
     return false; 
    } 
} 

コンパイラを実装するClassAのコードです。

class ClassA { 
String name; 
int id; 
String desc; 

public ClassA(String name, int id, String desc) { 
    this.name = name; 
    this.id = id; 
    this.desc = desc; 
} 

int getId() { 
    return id; 
    } 
} 

&

class CompareID implements Comparator<ClassA> { 
    int i = 0; 

    @Override 
    public int compare(ClassA o1, ClassA o2) { 
     System.out.println(i++);     // Counter variable 
     if (o1.getId() > o2.getId()) 
      return 1; 
     else if (o1.getId() < o2.getId()) 
      return -1; 
     else 
      return 0; 

    } 
} 

出力は、私はあなたが奇妙見つけているかわからないんだけど(また、デバッガで検証クロス)

0 
1 
2 
3 
0 // why started from 0 again ? 
1  
2 
3 
4 
5 
6 
7 
8 
4 // What the hell !!! 
5 
6 
7 
8 
Equal set of tree // is that correct output ? 
+1

あなたはそれが奇妙に見えるではない作るためにそこに何を期待するのと同じ出力の両方comperatorsを:コメントは出力を生成したものを含めますか? – SomeJavaGuy

+0

私はなぜそれが4の後に始まり、3の後にも0から始まるのか分からない。 – user3042916

+0

もう一度、あなたは何を見たいと思いますか?あなたが見ているものは、あなたが見たいものとはどのように異なっていますか?ニースの詳細。 – jwpfox

答えて

3

です。 2つの TreeSetインスタンスがあり、それぞれ独自のCompareIDインスタンスがComparatorとして機能し、各CompareIDインスタンスはそれ自身のカウンタを保持します。

したがって、各カウンタ値(0,1,2など)が2回表示されるのは驚くことではありません。 カウンタ値の表示順序は、内部実装TreeSetに依存します。木の

等しく設定については

は//正しい出力ということでしょうか?

はい、両方のセットに同じ要素が含まれています。順序は関係ありません。明確にするため - 方法containsTreeSetcontainsAllcompare(x,y)==0場合エレメントxcompareが供給Comparatorcompare方法であって、いくつかの要素TreeSetyTreeSetために含まれると考えます。したがって、あなたの例では、idプロパティだけが、2つの要素が等しいかどうかを判断します。

次のシナリオでは、出力を説明:

0 // compare method of 1st CompareID object executed 
1 // compare method of 1st CompareID object executed 
2 // compare method of 1st CompareID object executed 
3 // compare method of 1st CompareID object executed 
0 // compare method of 2nd CompareID object executed 
1 // compare method of 2nd CompareID object executed  
2 // compare method of 2nd CompareID object executed 
3 // compare method of 2nd CompareID object executed 
4 // compare method of 1st CompareID object executed 
5 // compare method of 1st CompareID object executed 
6 // compare method of 1st CompareID object executed 
7 // compare method of 1st CompareID object executed 
8 // compare method of 1st CompareID object executed 
4 // compare method of 2nd CompareID object executed 
5 // compare method of 2nd CompareID object executed 
6 // compare method of 2nd CompareID object executed 
7 // compare method of 2nd CompareID object executed 
8 // compare method of 2nd CompareID object executed 

EDIT:まず最初TreeSetに要素を追加する(したがってcompareComparatorのが一列に複数回呼ばれる)、その後、要素を追加します2番目のTreeSetにあるので(の2番目のComparatorを複数回呼び出す)、treeSetA.containsAll(treeSetB)と呼び出すと、最初にComparatorcompareが何度も呼び出され、最後にtreeSetB.containsAll(treeSetA)と呼ばれ、番目のComparatorのは、複数回連続して呼び出されます。

+0

'8'の後に '4'はどうなりますか? – user3042916

+0

"はい、両方のセットに同じ要素が含まれていますが、順序は関係ありません。 ---->要素が違う、名前と説明を見てください。 – user3042916

+1

@ user3042916これは、idプロパティだけを扱うので、コンパレータに関する限り同じ要素です。 – Eran

1

ここでは変数iは2つのコンパレータオブジェクトのために初期化され、ここではi = 0を初期化しています。ここでcompareメソッドが両方のセットに対して実行されますので、シーケンスは必要ありません実際には出力されません。

0// for set1(collection1) 
1 
2 
3 // remember this value for set 1 
0 // for set2(collection2) 
1  
2 
3 
4 
5 
6 
7 
8 
4 for set1(collection1 which was 3 and now increment to 1) 
5 
6 
7 
8 
1

変更するコードを以下とyou'll出力は次のように変更されたときに

class CompareID implements Comparator<ClassA> { 
    int i = 0; 
    String a; 
    public CompareID(String input) { 
     a = input; 
    } 
    @Override 
    public int compare(ClassA o1, ClassA o2) { 
     // Output comperator "id" 
     System.out.println(a+ " " + i++); // Counter variable 
     if (o1.getId() > o2.getId()) 
      return 1; 
     else if (o1.getId() < o2.getId()) 
      return -1; 
     else 
      return 0; 

    } 
} 

... 

    TreeSet<ClassA> treeSetA = new TreeSet<ClassA>(new CompareID("A")) { 
     { 
      addAll(collection1); 
     } 
    }; 

    TreeSet<ClassA> treeSetB = new TreeSet<ClassA>(new CompareID("B")) { 
     { 
      addAll(collection2); 
     } 
    }; 

出力をしているcomperator参照してください。 basicly

// This is addALL treeSetA 
A 0 
A 1 
A 2 
A 3 
// this is addAll treeSetB 
B 0 
B 1 
B 2 
B 3 
// this is treeSetA.containsAll(treeSetB) 
A 4 
A 5 
A 6 
A 7 
A 8 
// this is treeSetB.containsAll(treeSetA) 
B 4 
B 5 
B 6 
B 7 
B 8 

0-8 
0-8 
+0

私は不思議です、なぜあなたはそれが同期されていないのか説明できますか? – user3042916

+0

@ user3042916私はそれを編集しました、そこに何かが間違っている、出力のコメントは今助けてください;) – SomeJavaGuy