在定义treeMap的时候,重载了compare方法,本意是想在list中的,用元素在list所在的位置来比较顺序,如果不在list中,那么就用字典序来排序。
就写了下面的错误代码:
Map<Integer, Map<Long, MaterialType>> materialMap) {
Map<String, List<Object>> result = Maps.newTreeMap(
new Comparator<String>() {
public int compare(String obj1, String obj2) {
if (MaterialUtil.GridOrderList.contains(obj1) && MaterialUtil.GridOrderList.contains(obj2)) {
return MaterialUtil.GridOrderList.indexOf(obj1) - MaterialUtil.GridOrderList.indexOf(obj2);
} else {
logger.info(obj1 + " or " + obj2 + "is not in list, fail");
return obj1.compareTo(obj2);
}
}
});
这样是有问题的。因为假设A、B、C三个元素,A和C在list中,而B不在
list.add(C);
list.add(A);
如果按照list顺序排序,那么C排在A前面。
这时候,如果TreeMap 再添加一个key为B的。
由于B不在列表中,按照代码逻辑是按照字典序来排序。而B>A,说明B要排在A后面。B<C,说明B要排在C前面,故顺序应该为A,B,C。但是C和A比较的时候,C却是在A前面的。二者矛盾。
修改错误的代码。修改后为:
Map<String, List<Object>> result = Maps.newTreeMap(
new Comparator<String>() {
public int compare(String obj1, String obj2) {
if (MaterialUtil.GridOrderList.contains(obj1) && MaterialUtil.GridOrderList.contains(obj2)) {
return MaterialUtil.GridOrderList.indexOf(obj1) - MaterialUtil.GridOrderList.indexOf(obj2);
} else {
if (MaterialUtil.GridOrderList.contains(obj1)) {
return -1;
} else if (MaterialUtil.GridOrderList.contains(obj2)) {
return 1;
} else {
return obj1.compareTo(obj2);
}
}
}
});