向 TreeMap 添加条目时抛出 NullPointerException

以下代码在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:xx

k1:xz k2:xx

k1:cx k2:xx

k1:cx k2:xz

k1:ax k2:xz

k1:ax k2:xx

{ax=2, xx=5, xz=6, cx=9}

k1:dd k2:xz

Exception 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)


慕工程0101907
浏览 459回答 2
2回答

斯蒂芬大帝

很明显,HashMap比较里面有没有条目"dd":只"xx","xz","cx",和"ax"映射。这就是在等于时this.map.get(k1)产生的原因。nullk1"dd"之后你调用compareTo结果getthis.map.get(k1).compareTo(this.map.get(k2));//&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;---------它产生一个 NPE。要解决此问题,请添加一些替代方法来比较映射中没有键的对象 - 例如,通过比较键本身:public int compare(String k1, String k2){&nbsp; &nbsp; System.out.printf("k1:%s k2:%s\n",k1,k2);//for debugging&nbsp; &nbsp; Integer v1 = this.map.get(k1);&nbsp; &nbsp; Integer v2 = this.map.get(k2);&nbsp; &nbsp; if (v1 != null && v2 == null) {&nbsp; &nbsp; &nbsp; &nbsp; return -1;&nbsp; &nbsp; }&nbsp; &nbsp; if (v1 == null && v2 != null) {&nbsp; &nbsp; &nbsp; &nbsp; return 1;&nbsp; &nbsp; }&nbsp; &nbsp; return (v1 != null && v2 != null) ? v1.compareTo(v2) : k1.compareTo(k2);}

皈依舞

问题出现在这里&nbsp;return this.map.get(k1).compareTo(this.map.get(k2));您已经预定义了地图,this.map=map;但是如果您添加一个元素,则会调用比较器。但是由于该元素不在地图上还this.map.get(k1)返回null。这就是为什么你得到null.compareTo(...)导致异常的原因。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java