2016-12-21 6 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; 
} 
}); 

И при проверке ключа кастрированный баран существует, то он ответит неверно, но в определенном положении п-го я вижу, что пункт. Как это возможно? И в предыдущий элемент итерации был добавлен.

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. В подобных случаях обычно получается, что «Карта» - это неправильная структура данных, и вам действительно нужен отсортированный «Список». – 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); 
} 

Ключ вы ищете в карты и ключ вы положили в карты имеют различное состояние, так как вы обновляете rating2.userSetting().totalMatch внутри, если п.

Поэтому вполне возможно, что ключ, который вы ищете, не существует на карте, но ключ, который вы добавляете, существует на карте.

1

В Javadoc для TreeMap, вы читаете:

Обратите внимание, что порядок поддерживается картой дерева, как и любой отсортированной карта, и предоставляется ли или нет явного компаратор, должен быть согласован с равными, если это эта сортированная карта - это правильно реализовать интерфейс карты.

Поскольку вы не переопределяетесь equals, в вашем случае компаратора не согласуется с equals. Вы должны оборудовать свой UserSetting класс с equals способом, например:

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

Я бы рекомендовал использовать 'o.getClass()! = GetClass()' вместо 'instanceof', так как это может привести к асимметричному поведению' equals', когда дело доходит до подкласса ... –

+0

Я положил 'equals' в 'UserSetting', но он не имеет никакого эффекта, а' equals' не будет вызван. Любая идея почему? –

+0

@ János 'equals' не используется' TreeMap'. – Eran

0

Эран прямо в своем ответе выше. Ваш TreeMap не работает, потому что вы обновляете totalMatch. Этот код воспроизводит проблему.

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; 
     } 
    } 
} 
Смежные вопросы