2016-12-21 15 views
0

を誤動作私はTreeMapを持っている:のJavaのTreeMap

final Map<UserSetting, ItemsIntersectionAndComplement> _usersSimilar = new TreeMap<UserSetting, ItemsIntersectionAndComplement>(new Comparator<UserSetting>() { 

@Override 
public int compare(UserSetting lhs, UserSetting rhs) { 

int prec = (lhs.id()).compareTo(rhs.id()); 
return lhs.totalMatch > rhs.totalMatch ? -1 : (lhs.totalMatch < rhs.totalMatch) ? 1 : prec; 
} 
}); 

とキーが存在天気をチェックし、それが偽の応答するが、特定のn番目の位置に私は、その項目を参照してください。どのように可能ですか?そして、以前の反復項目では、項目が追加されました。

if (!_usersSimilar.containsKey(rating2.userSetting())) { // <-- CHECKING HERE EXISTENCE 

    ItemsIntersectionAndComplement iiac = new ItemsIntersectionAndComplement(); 
    iiac.intersection.add(rating2.item()); 
    rating2.userSetting().totalMatch = 1; 
    _usersSimilar.put(rating2.userSetting(), iiac); 
} else { 
    //.. SOME CODE, BUT CALL DOES NOT REACH IT 
} 

public class UserSetting extends _UserSetting { 
    public UserSetting() { 
    } 

    int totalMatch; 
} 
+0

なぜ-1?合理的な質問。 –

+0

存在を確認している場所にコメントを入れます –

+0

マップ内の変更可能なキーはお勧めできません。 [This](http://stackoverflow.com/questions/7842049/are-mutable-hashmap-keys-a-dangerous-practice)は 'HashMap'についてですが、' TreeMap'についても同様の議論ができます。同様のケースでは、通常、 'Map'は間違ったデータ構造であり、本当に必要なのはソートされた' List'です。 – biziclop

答えて

3
if (!_usersSimilar.containsKey(rating2.userSetting())) { // <-- CHECKING HERE EXISTENCE 

    ItemsIntersectionAndComplement iiac = new ItemsIntersectionAndComplement(); 
    iiac.intersection.add(rating2.item()); 
    rating2.userSetting().totalMatch = 1; 
    _usersSimilar.put(rating2.userSetting(), iiac); 
} 

あなたのif節内のrating2.userSetting().totalMatchを更新しているので、あなたは地図とあなたが地図に入れキーで探しているキーは、異なる状態を持っています。

したがって、検索しているキーはマップに存在しませんが、追加するキーはマップに存在する可能性があります。 TreeMapのJavadocで

1

、あなたが読んで:

注順序は任意のソートマップと同じように、ツリーマップによって維持、及び場合は、明示的なコンパレータが提供されているかどうか、equalsと一致していなければならないということこのソートマップは、Mapインターフェイスを正しく実装することです。あなたの場合には、コンパレータをequalsをオーバーライドしていないので

equalsと一致していません。あなたは、例えば、equals方法であなたのUserSettingクラスを装備する必要があります。

public boolean equals(Object o) { 
    if (this == o) { 
     return true; 
    } 
    if (!(o instanceof UserSetting)) { 
     return false; 
    } 
    UserSetting s = (UserSetting)o; 
    return id == s.id && totalMatch = s.totalMatch; 
} 
+2

'instanceof'の代わりに' o.getClass()!= getClass() 'を使うことをお勧めします。これは、サブクラス化に際して非対称な' equals'ビヘイビアを引き起こす可能性があるからです... –

+0

'equals' 'UserSetting'でも効果はなく、' equals'は呼び出されません。どんな考え? –

+0

@János 'equals'は' TreeMap'では使用されません。 – Eran

0

エランは、上記の彼の答えに右です。 totalMatchを更新しているため、TreeMapが壊れています。このコードは問題を再現します。

import java.util.Comparator; 
import java.util.Map; 
import java.util.TreeMap; 

public class HashMapWithComparatorTest { 
    public static void main(String[] args) { 
     final Map<UserSetting, String> _usersSimilar = new TreeMap<UserSetting, String>(new Comparator<UserSetting>() { 

      @Override 
      public int compare(UserSetting lhs, UserSetting rhs) { 

       int prec = (lhs.id()).compareTo(rhs.id()); 
       return lhs.totalMatch > rhs.totalMatch ? -1 : (lhs.totalMatch < rhs.totalMatch) ? 1 : prec; 
      } 
     }); 

     UserSetting setting1 = new UserSetting(2, 1); 
     UserSetting setting2 = new UserSetting(3, 1); 
     UserSetting setting3 = new UserSetting(1, 1); 
     UserSetting setting4 = new UserSetting(1, 1); 
     UserSetting setting5 = new UserSetting(2, 2); 

     _usersSimilar.put(setting1, "test"); 
     _usersSimilar.put(setting2, "test"); 
     _usersSimilar.put(setting3, "test"); 
     _usersSimilar.put(setting4, "test"); 


     System.out.println("Before touching totalMatch:"); 
     System.out.println(_usersSimilar.containsKey(setting1)); 
     System.out.println(_usersSimilar.containsKey(setting2)); 
     System.out.println(_usersSimilar.containsKey(setting3)); 
     System.out.println(_usersSimilar.containsKey(setting4)); 
     System.out.println(_usersSimilar.containsKey(setting5)); 

     setting1.totalMatch++; 
     setting1.totalMatch++; 

     setting2.totalMatch--; 
     setting2.totalMatch--; 

     setting3.totalMatch++; 
     setting3.totalMatch++; 

     setting4.totalMatch--; 
     setting4.totalMatch--; 

     setting5.totalMatch++; 
     setting5.totalMatch++; 

     System.out.println("After changing totalMatch:"); 
     System.out.println(_usersSimilar.containsKey(setting1)); 
     System.out.println(_usersSimilar.containsKey(setting2)); 
     System.out.println(_usersSimilar.containsKey(setting3)); 
     System.out.println(_usersSimilar.containsKey(setting4)); 
     System.out.println(_usersSimilar.containsKey(setting5)); 
    } 

    private static class UserSetting { 
     private int id; 
     public int totalMatch; 

     public Integer id() { 
      return id; 
     } 

     public UserSetting(int id, int totalMatch) { 
      this.id = id; 
      this.totalMatch = totalMatch; 
     } 
    } 
}