我已经创建了这样的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和equals和hash):
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 :(得分:3)
如果日期不同,比较器应返回-1 或 1,因为它必须是对称的,即如果在比较date1
和date2
时返回-1比较date2
和date1
时必须返回1。您的代码必然会破坏地图,因为它无法可靠地确定密钥的顺序。
因此,将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;
编辑:对比较器可能发生的情况进行细分。
如果您查看了来源,您会看到地图会将新密钥与现有密钥进行比较。因此,您的比较器将根据插入顺序对它们进行排序,即,因为对于非相等键,您总是返回-1,因此地图将始终跟随左分支,因此最后添加的元素将是&#34;最小的&#34;。这只是另一个问题。
您遇到的问题可以在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
,因为没有剩余的元素,然后是while循环已终止,您最终到达return null;
。