2017-03-17 10 views
2

私は奇妙な動作を経験していますが、その理由がわかりません。 LinkedHashSetから要素を削除しようとしましたが、削除されていません。リンクされたハッシュセットが削除されない

私のクラスのドキュメントが定義されてい

protected Set<Author> authors = new LinkedHashSet<>(); 

idrole両方が等しいときに著者が等しい::

@Override 
public int hashCode() { 
    int hash = 7; 
    hash = 53 * hash + Objects.hashCode(this.id); 
    hash = 53 * hash + Objects.hashCode(this.role); 
    System.out.println("Calling hashcode: " + hash); 
    return hash; 
} 

@Override 
public boolean equals(Object obj) { 
    System.out.println("Calling equals"); 
    if (obj == null) { 
     return false; 
    } 
    System.out.println("1"); 
    if (getClass() != obj.getClass()) { 
     return false; 
    } 
    System.out.println("2"); 
    final Author other = (Author) obj; 
    if (!Objects.equals(this.id, other.id)) { 
     return false; 
    } 
    System.out.println("3"); 
    if (!Objects.equals(this.role, other.role)) { 
     return false; 
    } 
    System.out.println("4"); 
    return true; 
} 

その後、いくつかのデバッグ印刷と削除コード:

public void removeAuthor(Author author) { 
    System.out.println(">removeAuthor [" + author.hashCode() + "]: " + author); 
    if (document.getAuthors() != null) { 
     System.out.println("[" + document.getAuthors().size() + "] Authors BEFORE:"); 
     document.getAuthors().forEach((pp) -> { 
      System.out.println("[" + pp.hashCode() + "] " + pp); 
     }); 
    } 

    if (document != null) { 
     if (document.getAuthors() != null) { 
      document.getAuthors().remove(author); 
     } 
    } 

    if (document.getAuthors() != null) { 
     System.out.println("[" + document.getAuthors().size() + "] Authors AFTER:"); 
     document.getAuthors().forEach((pp) -> { 
      System.out.println("[" + pp.hashCode() + "] " + pp); 
     }); 
    } 
} 

これは以下を印刷します(私は私のcomを追加しますメント):

// Call to hashCode() to print the author that will be removed 
    Calling hashcode: 400605768 
// Author that will be removed 
    >removeAuthor [400605768]: Author{id=self, name=Self Centre, forename=null, familyName=null, role=Writer} 
// List before calling remove, it gives 2 authors 
    [2] Authors BEFORE: 
    Calling hashcode: -1820871746 
    [-1820871746] Author{id=self, name=Self Centre, forename=null, familyName=null, role=Researcher} 
    Calling hashcode: 400605768 
    [400605768] Author{id=self, name=Self Centre, forename=null, familyName=null, role=Writer} 
// This hashCode call is probably done by remove(). As it can be seen, the object to be removed *is* on the Set 
    Calling hashcode: 400605768 
// List after calling remove, it gives again 2 authors 
    [2] Authors AFTER: 
    Calling hashcode: -1820871746 
    [-1820871746] Author{id=self, name=Self Centre, forename=null, familyName=null, role=Researcher} 
    Calling hashcode: 400605768 
    [400605768] Author{id=self, name=Self Centre, forename=null, familyName=null, role=Writer} 
    Calling hashcode: -1820871746 

一般的にセットを使用するのに使用します。それは愚かな間違いかもしれないが、私はそれがどこにあるのか分からない。また、compareToや他のメソッドは、等価性のテストには使用されていないようです。

+1

[最小限のテストケース](https://stackoverflow.com/help/mcve)を作成できますか? –

+0

メソッドが含まれているときに持っているもの。 'document.getAuthors()。contains(author)'? –

+0

Author.roleとはどのようなタイプですか?そのカスタムクラスにもequalsが実装されていますか? –

答えて

0

デバッグのお陰でミステリーを解決したと思います。 Ajaxの使用には間違いありません。 LinkedHashSetを作成するとき、その要素は、hashCodeに基づくインデックスのハッシュテーブルに追加されます。場合によっては、AjaxのJSF操作でメモリー内のオブジェクトのroleが変更され、ハッシュが変更されることがあります。しかし、最初に挿入されたハッシュテーブル内の位置は全く変更されていません!したがって、削除する特定のハッシュを持つ要素があります。要素はセット内に存在します(実際のコードは同じです)が、実際のコードではtable[ (table.length-1) & hash ]から要素を削除しようとすると、それはその位置にないため、最初は別のハッシュ値で追加されました。これはミステリーを解決し、それは完全に論理的です。

+0

実際にはそれほど深刻ではありません。一部のAjaxメソッドでは、(他の属性の中でも)ロールの変更が可能であり、完全に分かりやすく、キーの一部となることがあります。このような変更が発生した場合、設定された要素を削除して再度挿入する必要があります。 – user1156544

+0

現在管理中です。ありがとう! =) – user1156544

関連する問題