为了账号安全,请及时绑定邮箱和手机立即绑定

向 TreeMap 添加条目时抛出 NullPointerException

向 TreeMap 添加条目时抛出 NullPointerException

慕工程0101907 2021-12-10 10:09:34
以下代码在tm.put("dd",7);. 为什么是这样?我已经添加了调试,看起来我的比较函数是错误的,但我委托给 String.compare。如何修复它以便我可以向 TreeMap 添加新条目并自动按 VALUE 对新条目进行排序?谢谢。编辑我遇到的问题是,据我所知,TreeMap 应该连续排序 - 您应该能够将条目添加到已经填充的 TM 中,并按排序顺序保持地图。到目前为止给出的解决方案不允许我这样做。当我添加 ("cc",7) 时,我希望该条目根据我提供给构造函数的比较器“插入”。这应该是可能的,不是吗?EDIT2我现在可以看到这可能是不可能的,因为比较器对象用于查找值的映射是在构造时提供的。可能有办法解决这个问题,但我看不到它。static void f16(){        Map<String,Integer> hm = new HashMap<>();        hm.put("xx",5);        hm.put("xz",6);        hm.put("cx",9);        hm.put("ax",2);        class ValueComparator implements Comparator<String> { //satisfies Comparator<K> req of TreeMap const            Map<String,Integer> map;            ValueComparator(Map<String,Integer> map){                this.map=map;            }            public int compare(String k1, String k2){                System.out.printf("k1:%s k2:%s\n",k1,k2);//for debugging                return this.map.get(k1).compareTo(this.map.get(k2));            }        }        ValueComparator valueComp = new ValueComparator(hm);        NavigableMap<String,Integer> tm = new TreeMap<>(valueComp);        tm.putAll(hm);        System.out.println(tm);                tm.put("dd",7); //throws NPE        System.out.println(tm);  }控制台输出:k1:xx k2:xxk1:xz k2:xxk1:cx k2:xxk1:cx k2:xzk1:ax k2:xzk1:ax k2:xx{ax=2, xx=5, xz=6, cx=9}k1:dd k2:xzException in thread "main" java.lang.NullPointerException        at T1$1ValueComparator.compare(T1.java:28)        at T1$1ValueComparator.compare(T1.java:21)        at java.util.TreeMap.put(TreeMap.java:552)        at T1.f16(T1.java:35)        at T1.main(T1.java:10)
查看完整描述

2 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

很明显,HashMap比较里面有没有条目"dd":只"xx","xz","cx",和"ax"映射。这就是在等于时this.map.get(k1)产生的原因。nullk1"dd"


之后你调用compareTo结果get


this.map.get(k1).compareTo(this.map.get(k2));

//               ---------

它产生一个 NPE。


要解决此问题,请添加一些替代方法来比较映射中没有键的对象 - 例如,通过比较键本身:


public int compare(String k1, String k2){

    System.out.printf("k1:%s k2:%s\n",k1,k2);//for debugging

    Integer v1 = this.map.get(k1);

    Integer v2 = this.map.get(k2);

    if (v1 != null && v2 == null) {

        return -1;

    }

    if (v1 == null && v2 != null) {

        return 1;

    }

    return (v1 != null && v2 != null) ? v1.compareTo(v2) : k1.compareTo(k2);

}


查看完整回答
反对 回复 2021-12-10
?
皈依舞

TA贡献1851条经验 获得超3个赞

问题出现在这里 return this.map.get(k1).compareTo(this.map.get(k2));

您已经预定义了地图,this.map=map;但是如果您添加一个元素,则会调用比较器。但是由于该元素不在地图上还this.map.get(k1)返回null。这就是为什么你得到null.compareTo(...)导致异常的原因。


查看完整回答
反对 回复 2021-12-10
  • 2 回答
  • 0 关注
  • 458 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号