简体   繁体   English

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

[英]TreeSet throws nullpointer exception when using custom comparator

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.我不确定为什么会发生这种情况,我尝试使用 contains 来检查集合中是否已经存在可以正常工作的相同元素。 The exception throws when calling reset method.调用 reset 方法时抛出异常。

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<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); //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);
 */

As @VGR mentioned: Are you certain that HS.get(a) never returns null in your compare method?正如@VGR 提到的:您确定 HS.get(a) 在您的比较方法中永远不会返回 null 吗?

This is because that the TreeMap is based on HashMap to compare.这是因为 TreeMap 是基于 HashMap 来比较的。 If delete the HS value using HS.remove(a), whenever the treemap call HS.get(a) there will be a null as return value.如果使用 HS.remove(a) 删除 HS 值,则无论何时 treemap 调用 HS.get(a) 都会有一个 null 作为返回值。 which when called in compare for HS.get(a).compareTo will be null.compareTo, and this is the reason that throws an NullPointerException.当为 HS.get(a).compareTo 调用 compare 时,它​​将是 null.compareTo,这就是抛出 NullPointerException 的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM