写了一个需要排序的map,自定义了一个comparator,但是在取值时,一直为null,固有此文章
错误代码如下:
// 这里是错误的代码// 代码可以正确排序,但是却不能正确取值。Map<String, Object> allResult = new TreeMap<>((o1, o2) -> {Date dateO1 = DateUtilPlus.parse(o1, DateUtilPlus.DATE_FORMAT);Date dateO2 = DateUtilPlus.parse(o2, DateUtilPlus.DATE_FORMAT);if (null == dateO1 || null == dateO2) {return 0;}return dateO1.before(dateO2) ? -1 : 1;});allResult.put("2018-11-30", "dddd");allResult.put("2018-11-27", "dddd");allResult.put("2018-11-28", "dddd");allResult.put("2018-11-29", "dddd");System.out.println(allResult.get("2018-11-28"));// get结果,一直是null
查看源码发现,如果自定义了comparator,get方法会根据自定义的comparator的结果查找value
public V get(Object key) {Entry<K,V> p = getEntry(key);return (p==null ? null : p.value);}final Entry<K,V> getEntry(Object key) {// Offload comparator-based version for sake of performanceif (comparator != null)// 如果自定义了comparatorreturn getEntryUsingComparator(key);// 此下代码没用,省略。。。}/** 使用自定义comparator查询 */final Entry<K,V> getEntryUsingComparator(Object key) {@SuppressWarnings("unchecked")K k = (K) 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// 如果比较器返回0,说明找到了key对应的valuereturn p;}}return null;}
修改后的正确的map代码:
Map<String, Object> allResult = new TreeMap<>((o1, o2) -> {if(StringUtils.isBlank(o1) || StringUtils.isBlank(o2)){return -1;}if(o1.equals(o2)){return 0;}Date dateO1 = DateUtilPlus.parse(o1, DateUtilPlus.DATE_FORMAT);Date dateO2 = DateUtilPlus.parse(o2, DateUtilPlus.DATE_FORMAT);if (null == dateO1 || null == dateO2) {return -1;}return dateO1.before(dateO2) ? -1 : 1;});
