web-dev-qa-db-ja.com

Java.Setの使用方法

私はかなり長い間それを機能させようとしていますが、それを得ることができないようです。オブジェクトタワーがブロックで構築されています。私はすでに配列を使用して動作するようにしましたが、Setを学びたかったのです。これと同様の機能を取得したい:

public class Tower {


public Tower(){
}

public Tower add(Block k1){

    //(...)
    //if block already in tower, return "Block already in tower"
}

public Tower delete(Block k1){

    //(...)
    //if block already dleted, show "No such block in tower"
}

}

誰かがコードをくれましたが、それを使おうとするといつもエラーが出ます:

Set<Block> tower = new HashSet<Block>();

boolean added = tower.add( k1 );
if( added ) {
System.out.println("Added 1 block.");
} else {
System.out.println("Tower already contains this block.");
}

実装方法

15
owca

最初に学習する必要があるのは _Java.util.Set_ API です。

メソッドの使用方法の小さな例を次に示します。

_    Set<Integer> numbers = new TreeSet<Integer>();

    numbers.add(2);
    numbers.add(5);

    System.out.println(numbers); // "[2, 5]"
    System.out.println(numbers.contains(7)); // "false"

    System.out.println(numbers.add(5)); // "false"
    System.out.println(numbers.size()); // "2"

    int sum = 0;
    for (int n : numbers) {
        sum += n;
    }
    System.out.println("Sum = " + sum); // "Sum = 7"

    numbers.addAll(Arrays.asList(1,2,3,4,5));
    System.out.println(numbers); // "[1, 2, 3, 4, 5]"

    numbers.removeAll(Arrays.asList(4,5,6,7));
    System.out.println(numbers); // "[1, 2, 3]"

    numbers.retainAll(Arrays.asList(2,3,4,5));
    System.out.println(numbers); // "[2, 3]"
_

APIに慣れたら、それを使用してより興味深いオブジェクトを含めることができます。 equals および hashCode の契約にまだ慣れていない場合は、今から始めるのがよいでしょう。

手短に:

  • _@Override_bothまたはnone; 1つだけではありません。(非常に重要です。プロパティを満たす必要があるためです:a.equals(b) == true --> a.hashCode() == b.hashCode()
    • 代わりにboolean equals(Thing other)と書くことに注意してください。これは適切な_@Override_ではありません。
  • Null以外の参照_x, y, z_の場合、equalsは次のようにする必要があります。
    • 再帰的:x.equals(x)
    • 対称:x.equals(y)は、y.equals(x)の場合にのみ
    • 推移的:x.equals(y) && y.equals(z)の場合、x.equals(z)
    • 整合性:x.equals(y)は、オブジェクトが変更されていない限り変更してはなりません
    • x.equals(null) == false
  • hashCodeの一般契約は次のとおりです:
    • 一貫性:突然変異が発生しない限り、同じ数を返します
    • equalsと一致:x.equals(y)の場合、x.hashCode() == y.hashCode()
      • 厳密に言えば、オブジェクトの不等式はハッシュコードの不等式を必要としません
      • ただし、ハッシュコードの不等式には必然的にオブジェクトの不等式が必要です
  • 突然変異と見なされるものは、equalshashCodeの間で一貫している必要があります。

次に、オブジェクトの順序付けを行いたい場合があります。これを行うには、型に Comparable を実装させるか、別の Comparator を指定します。

どちらかを使用すると、オブジェクトの並べ替えが簡単になります(_Arrays.sort_、Collections.sort(List))。また、SortedSetなどのTreeSetを使用することもできます。


Stackoverflowの詳細情報:

54

Blockクラスで equals and hashCode をオーバーライドしましたか?

編集:

私はあなたがそれが実行時に機能しないことを意味すると仮定しました...あなたはそれを意味しましたか、それともコンパイル時にですか?コンパイル時にエラーメッセージは何ですか?実行時にクラッシュした場合、スタックトレースは何ですか?コンパイルして実行しても正しく機能しない場合は、equalsとhashCodeが問題になる可能性があります。

2
TofuBeer

与えられた情報でこの質問に答えることは困難です。 HashSetの使用方法に特に問題はありません。

まあ、それはコンパイルの問題ではないという推測を危険にさらすでしょう、そして、あなたが「エラーを取得する」と言うとき、あなたは「あなたが望む行動を得ていない」ことを意味します。

また、私は手足に出て、おそらくあなたのBlockのequalsとhashCodeメソッドが適切にオーバーライドされないことを提案します。

1
MaxGuernseyIII

HashSetであるため、hashCodeおよびequalsメソッドをオーバーライドする必要があります。 http://preciselyconcise.com/Java/collections/d_set.php には、hashCodeメソッドとequalsメソッドを実装する方法を説明する例があります

0
Sai Sunder