TreeSet在使用自定义比较器时抛出空指针异常。

huangapple go评论70阅读模式
英文:

TreeSet throws nullpointer exception when using custom comparator

问题

以下是您提供的代码段的翻译部分:

我在尝试从TreeSet中删除特定元素非null时遇到了错误消息我不确定为什么会发生这种情况我尝试使用contains方法检查集合中是否已经存在相同的元素这样可以正常工作异常在调用reset方法时抛出

    java.lang.NullPointerException
      在第55行Leaderboard$1.compare
      在第52行Leaderboard$1.compare
      在第374行java.base/java.util.TreeMap.getEntryUsingComparator
      在第343行java.base/java.util.TreeMap.getEntry
      在第601行java.base/java.util.TreeMap.remove
      在第276行java.base/java.util.TreeSet.remove
      在第86行Leaderboard.reset
      在第71行__Driver__.__helperSelectMethod__
      在第91行__Driver__.__helper__
      在第112行__Driver__.main

> 这是我的代码

    class Leaderboard {
        TreeSet<Integer> TS;
        HashMap<Integer, Integer> HS = new HashMap<>();
        public Leaderboard() {
            TS = new TreeSet<>(new Comparator<Integer>(){
               @Override
                public int compare(Integer a, Integer b){
                    if(HS.get(a).equals(HS.get(b))){
                        return Integer.compare(a, b);
                    }
                    return HS.get(a).compareTo(HS.get(b));
                }
            });
        }
        
        public void addScore(int playerId, int score) {
            HS.put(playerId, HS.getOrDefault(playerId, 0) + score);
            TS.add(playerId);
            TreeSet<Integer> test = TS;
            HashMap<Integer, Integer> test2 = HS;
        }
        
        public int top(int K) {
            Iterator<Integer> iterator = TS.iterator();
    
            int res = 0;
            while(K > 0 && iterator.hasNext()){
                res += HS.get(iterator.next());
                K--;
            }
            return res;
        }
        
        public void reset(int playerId) {
            Integer id = new Integer(playerId); //尝试过,无效
            System.out.println(HS.containsKey(id)); // true        
            System.out.println(TS.contains(id)); // true
            HS.remove(id);
            TS.remove(id);
        }
    }
    
    /**
     * 将实例化您的Leaderboard对象,并按以下方式调用:
     * Leaderboard obj = new Leaderboard();
     * obj.addScore(playerId, score);
     * int param_2 = obj.top(K);
     * obj.reset(playerId);
     */
英文:

I got an error msg when I trying to remove a specific element in treeset (not null). I'm not sure why this happened, and I tried to use contains to check if there has the same element in the set already which would work fine. The exception throws when calling reset method.

java.lang.NullPointerException
at line 55, Leaderboard$1.compare
at line 52, Leaderboard$1.compare
at line 374, java.base/java.util.TreeMap.getEntryUsingComparator
at line 343, java.base/java.util.TreeMap.getEntry
at line 601, java.base/java.util.TreeMap.remove
at line 276, java.base/java.util.TreeSet.remove
at line 86, Leaderboard.reset
at line 71, __Driver__.__helperSelectMethod__
at line 91, __Driver__.__helper__
at line 112, __Driver__.main

> Here is my code:

class Leaderboard {
TreeSet&lt;Integer&gt; TS;
HashMap&lt;Integer, Integer&gt; HS = new HashMap&lt;&gt;();
public Leaderboard() {
TS = new TreeSet&lt;&gt;(new Comparator&lt;Integer&gt;(){
@Override
public int compare(Integer a, Integer b){
if(HS.get(a).equals(HS.get(b))){
return Integer.compare(a, b);
}
return HS.get(a).compareTo(HS.get(b));
}
});
}
public void addScore(int playerId, int score) {
HS.put(playerId, HS.getOrDefault(playerId, 0) + score);
TS.add(playerId);
TreeSet&lt;Integer&gt; test = TS;
HashMap&lt;Integer, Integer&gt; test2 = HS;
}
public int top(int K) {
Iterator&lt;Integer&gt; iterator = TS.iterator();
int res = 0;
while(K &gt; 0 &amp;&amp; iterator.hasNext()){
res += HS.get(iterator.next());
K--;
}
return res;
}
public void reset(int playerId) {
Integer id = new Integer(playerId); //tried, not work
System.out.println(HS.containsKey(id)); // true        
System.out.println(TS.contains(id)); // true
HS.remove(id);
TS.remove(id);
}
}
/**
* Your Leaderboard object will be instantiated and called as such:
* Leaderboard obj = new Leaderboard();
* obj.addScore(playerId,score);
* int param_2 = obj.top(K);
* obj.reset(playerId);
*/

答案1

得分: 0

如@VGR所提到的:
您确定在您的比较方法中HS.get(a)永远不会返回null吗?

这是因为TreeMap是基于HashMap进行比较的。如果使用HS.remove(a)删除了HS的值,无论何时treemap调用HS.get(a),都会返回null作为返回值。当在比较中为HS.get(a).compareTo调用时,将会是null.compareTo,这就是抛出空指针异常的原因。

英文:

As @VGR mentioned:
Are you certain that HS.get(a) never returns null in your compare method?

This is because that the TreeMap is based on HashMap to compare. If delete the HS value using HS.remove(a), whenever the treemap call HS.get(a) there will be a null as return value. which when called in compare for HS.get(a).compareTo will be null.compareTo, and this is the reason that throws an NullPointerException.

huangapple
  • 本文由 发表于 2020年9月25日 07:22:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/64055697.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定