2016-09-12 3 views
-2

Я создал TreeMap так:Java TreeMap возвращает нуль для ключа, когда значение существует

Map<Date, List<MyInput>> inputsByDate = new TreeMap<>(new Comparator<Date>() { 
     @Override 
     public int compare(Date lhs, Date rhs) { 
      return dateUtil.compareDay(lhs, rhs); 
     } 


    }); 

Мой метод в компараторе не очень, но по крайней мере определяет сходство (я не использую HashMap с равными и хэш из-за других причин):

public int compareDay(Date lhs, Date rhs) { 
    Calendar cal1 = Calendar.getInstance(); 
    Calendar cal2 = Calendar.getInstance(); 
    cal1.setTime(lhs); 
    cal2.setTime(rhs); 
    boolean sameDay = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && 
      cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR); 
    if (sameDay) { 
     return 0; 
    } else { 
     return -1; 
    } 
} 

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

public List<MyType> convert(Map<Date, List<MyInput>> inputByDate, Map<Date, Boolean> isDoneByDate) { 
     List<MyType> result = Lists.newArrayList(); 
     for (Date dateKey : inputByDate.keySet()) { 
      boolean isDone = false; 
      Boolean res = isDoneByDate.get(dateKey); 
      if (res != null) { 
       isDone = res; 
      } 
      List<MyInput> inputs = inputByDate.get(dateKey); 

      MyType retrieved=new MyType(dateKey, inputs, isDone); 
      result.add(retrieved); 
     } 
     return result; 
    } 

Когда я бегу последний фрагмент кода с помощью отладчика я могу ясно видеть, что есть (в качестве примера) 3 клавиши со значениями, которые не нулевой. Я должен упустить что-то здесь, потому что я не вижу, как отчеты могут быть пустыми, если я проверял, что каждый ключ сопоставляется с действительной парой. Любая помощь будет принята с благодарностью.

+0

Компаратор должен определить <, ==, >, а не только == и! =. Это отрицательное значение 0 или положительное возвращаемое значение. Проверьте документы для компараторов. -1 означает lhs

+0

Btw, вы имеете в виду 'inputByDate.keySet()' вместо 'inputByDate()'? И что такое 'reportsByDay'? – Thomas

+0

Мой плохой, моя «обфускация», которую я применил к моему фактическому коду, была неисправна. Исправлено сейчас. –

ответ

3

Если даты различны ваш компаратор должен возвращать -1 или 1, так как он должен быть симметричным, т.е. если вы возвращаете -1 при сравнении date1 и date2 вы должны вернуть 1 при сравнении date2 и date1. Ваш код обязан разорвать карту, поскольку он не может надежно определить порядок для ключей.

Так реорганизовать compare() к чему-то вроде этого:

int result = Integer.compare(cal1.get(Calendar.YEAR), cal2.get(Calendar.YEAR)); 
if(result == 0) { //if the year is equal compare the days 
    result = Integer.compare(cal1.get(Calendar.DAY_OF_YEAR), cal2.get(Calendar.DAY_OF_YEAR)); 
} 
return result; 

Edit: Небольшая разбивку на то, что, вероятно, произошло с компаратором.

Если вы посмотрите на источники, вы увидите, что карта будет сравнивать новый ключ с уже существующими ключами. Таким образом, ваш компаратор упорядочивает их в соответствии с порядком вставки, т. Е. Поскольку вы всегда возвращаете -1 для неравных ключей, карта всегда будет следовать левой ветке, и, таким образом, последний добавленный элемент будет «самым маленьким». Но это еще одна проблема.

Проблема, с которой вы столкнулись, находится в методе getEntryUsingComparator(), который косвенно называется get(key). Метод выглядит следующим образом:

Comparator<? super K> cpr = comparator; 
if (cpr != null) { 
    Entry<K,V> p = root; 
    while (p != null) { 
    int cmp = cpr.compare(k, p.key); 
    if (cmp < 0) 
     p = p.left; 
    else if (cmp > 0) 
     p = p.right; 
    else 
     return p; 
    } 
} 
return null; 

Как вы можете видеть из-за всегда возвращается -1 методы не всегда будут выполнять cmp < 0 ветви до p = p.left результатов в p = null, потому что нет более левого элемент, а затем цикл в то время как завершается и вы попадаете в return null;.

+0

Я знал, что компаратор не симметричен, но я подумал: «Трахайтесь, у меня никогда не будет более 10 ключей на этой карте». Это был плохой ход, потому что теперь он работает. –

+0

@why_vincent рад слышать, как это работает сейчас. – Thomas

Смежные вопросы