TreeMap 集合之强制存储重复键之后get到null值

前段时间工作中用到TreeMap集合,好久没用过以至于忘了会get到null值,现在把这个Mark一下。
问题描述:本来TreeMap是用来**去重**并排序的。当我们因为需要**强制其存储重复键值**的时候,通过get去

获取对应的值就会发生错误,取出null值。
以下简单写一个Demo:

        Map<Integer, String> map = new TreeMap<>(new Comparator<Integer>() {

            public int compare(Integer i1, Integer i2) {
                // TODO Auto-generated method stub
                int num = i1 - i2;
                return num == 0 ? 1 : num;
            }
        });

        map.put(1, "一");
        map.put(2, "二");
        map.put(3, "三");
        map.put(1, "四");

        System.out.println(map.get(1));
以上会get到null值,究其原因,可以从get方法源码中找到答案。TreeMap集合中实现Map集合的get代码如下:
    public V get(Object key) {
        Entry<K,V> p = getEntry(key);
        return (p==null ? null : p.value);
    }

再继续往下看 getEntry(key)方法:

 final Entry<K,V> getEntry(Object key) {
        // Offload comparator-based version for sake of performance
        if (comparator != null)
            return getEntryUsingComparator(key);
  //以下代码省略

这个时候就已经很明显了,他用到了我们传入的比较器!!!
接着往下看getEntryUsingComparator(key);

 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
                    return p;
            }
        }
        return null;
    }

这个就很明白了,底层在往出取值的时候用到了我们传入的比较器中的compare()方法,TreeMap是二叉树结构存储数据。当我们拿着键去get值时,底层拿着我们传入的键去逐个比对此处调用比较器中的compare方法:小于零则往左边去找,大于零往右去找,只有当等于0时才返回该值,而我们强制compare()方法等于0的时候返回1,所以一直往右边去找,永远找不到,直到最后返回null

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值