2

と(スーパークラスで)LinkedHashSetを実装するオブジェクトがありますが、その正確なオブジェクトをセットから削除しようとすると、remove メソッドが戻り、オブジェクトがセットに残ります。の実装は、そのオブジェクトのメソッドを呼び出すことになっていますか? そうではないからです。これはJavaのバグでしょうか?1.6.0_25 を実行しています。equalshashCodecompareToset.remove(obj)falseLinkedHashSetequals()

4

3 に答える 3

5

オブジェクトのhashCode()実装は、オブジェクトをセットに追加したときとは異なる値を返していると思います。

于 2011-10-26T02:13:36.093 に答える
0

これがバグである可能性LinkedHashSet限りなく小さいです。これは、問題のもっともらしい説明として却下する必要があります。

これがコードのバグであると仮定すると、さまざまな原因が考えられます。例えば:

  • あなたequalshashCodeメソッドは、オブジェクトに対して矛盾する答えを返しています。
  • equalsまたはメソッドhashCodeは変更可能なフィールドに依存しており、オブジェクトがセット内にある間にそれらのフィールドが変更されています。(たとえば、ハッシュコード値が変更された場合、オブジェクトは間違ったハッシュ チェーンにある可能性が高く、removeメソッドがそれを見つけられなくなります。)
  • equalsメソッドを のオーバーライドではなく、オーバーロードとして宣言しましたequals(Object)。(それはあなたequalsが呼び出されていない理由を説明することができます...あなたの主張が事実上正しいと仮定します。)
  • 削除しようとしているオブジェクトは、(実際には) 挿入したオブジェクトではありません。
  • 他の何かがオブジェクトを既に削除しています。
  • 調べているソース コードと一致しないクラスの別のバージョンを実行しています。

さて、あなたがこれらの説明のいくつかを却下したことを私は知っています. しかし、それは時期尚早だったかもしれません。その解雇の根拠となった証拠を確認してください。

もう 1 つの方法は、Java デバッガーを使用してデータ構造 (.ini ファイルの内部などLinkedHashSet) を法医学的に調べ、削除が行われているはずのコードを 1 ステップ実行することです。

于 2011-10-26T02:32:03.357 に答える
0

LinkedHashSet私にとってはうまくいきます:

import java.util.*;

public class Test {
    public static void main( String[] args ) {
        LinkedHashSet<String> lhs = new LinkedHashSet<String>();
        String s = "hi";
        lhs.add( s );
        System.out.println( lhs );
        lhs.remove( s );
        System.out.println( lhs );
    }
}

おそらく、別のオブジェクトへの参照を remove メソッドに渡していますか? 参照を変更していないことを確認しますか?

また、hashCode()挿入したときに削除しようとしているときと同じ値を返すことを確認してください。

于 2011-10-26T02:12:32.127 に答える