HashMap的基于hash表的实现机制决定了他非常快的检索速度,但也定了“不能排序”的标牌,工作中如果需要排序就要使用TreeMap
TreeMap是可排序map,可对ke进行排序,那么,是不是任何我们原来使用HashMap实现的业务都能使用TreeMap进行替换排序呢?
答案是:“否”
原因在于,它们判断重复元素机制不同:HashMap通过hashcode和equals方法来判断重复,以决定是否加入到map中
而TreeMap则是通过排序码来决定的,也就是实现Comparator元素的compare中使用到的排序码(通常与我们的业务有关系),如果排序码相同则不加入到TreeMap中,
实际工作中,HashMap中完全可能存在这种元素,因为HashMap的实现机制并没有阻止这种排序码相同的元素加入,所以不能简单的将Hashmap替换为TreeMap以完成元素排序,下面的这个例子演示了这个错误:
public static void main(String[] args) {
class Obj implements Comparable<Obj> {
int c;
public Obj(int c) {
this.c = c;
}
@Override
public int compareTo(Obj o) {
return 0;//这里隐含了排序码
}
}
Map hashMap = new HashMap();
hashMap.put(new Obj(1),new Obj(0));
hashMap.put(new Obj(3),new Obj(0));
hashMap.put(new Obj(5),new Obj(0));
hashMap.put(new Obj(2),new Obj(0));
hashMap.put(new Obj(4),new Obj(0));
System.out.println(hashMap);//5个元素
Map treeMap = new TreeMap();
treeMap.putAll(hashMap);
System.out.println(treeMap);//1个元素
}
上面的代码演示出:原先hashmap中的5个元素,被导入到treemap中后变成了1个,慎重!
所以千万不要直接将hashmap想当然地替换为treemap,你最好评估下是否会产生这种问题。
hashmap排序解决方案:
将hashmap的entry放入到list中,对list排序就好了,实例代码:
public static void main(String[] args) {
class Obj implements Comparable<Obj> {
int c;
public Obj(int c) {
this.c = c;
}
@Override
public int compareTo(Obj o) {
return 0;//这里隐含了排序码
}
}
Map hashMap = new HashMap();
hashMap.put(new Obj(1), new Obj(0));
hashMap.put(new Obj(3), new Obj(0));
hashMap.put(new Obj(5), new Obj(0));
hashMap.put(new Obj(2), new Obj(0));
hashMap.put(new Obj(4), new Obj(0));
System.out.println(hashMap);//5个元素
List<Map.Entry<Obj, Obj>> list = new ArrayList<Map.Entry<Obj, Obj>>();
list.addAll(hashMap.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Obj, Obj>>() {
@Override
public int compare(Map.Entry<Obj, Obj> o1, Map.Entry<Obj, Obj> o2) {
return o1.getKey().c - o2.getKey().c;
}
});
for (Map.Entry<Obj, Obj> entry : list) {
System.out.println(entry.getKey().c);
}
}