Map 排序 TreeMap 陷阱

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);
        }
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值