You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中从HashMap移除键时触发java.lang.NullPointerException问题

LeetCode《Top K Frequent Elements》代码空指针异常问题

我在解决LeetCode《Top K Frequent Elements》题目时,代码执行到hm.remove(currentGreatestValue);这一行抛出了java.lang.NullPointerException异常。我的需求是在迭代过程中从HashMap移除键,以此获取下一个最大元素,相关代码如下:

class Solution {
    public int[] topKFrequent(int[] nums, int k) {

        HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
        for (int i=0; i<nums.length; i++){
            if (!hm.containsKey(nums[i])){
                hm.put(nums[i], 1);
            } else {
                int occurances = hm.get(nums[i]);
                occurances = occurances + 1;
                hm.put(nums[i], occurances);
            }
        }
   
        int mostOccuredValues[] = new int[k]; 

        Iterator hmIterator = hm.entrySet().iterator();

        int currentGreatestValue=0;
        int currentValue;

        int nextGreatestIndex=0;


        for (int i=0; i<k; i++){
            while (hmIterator.hasNext()) {
                Map.Entry mapElement = (Map.Entry)hmIterator.next();
                currentValue = (int)mapElement.getKey();
                if (currentValue>currentGreatestValue){
                    currentGreatestValue = currentValue;
                }
            }
            mostOccuredValues[nextGreatestIndex] = hm.get(currentGreatestValue);
            nextGreatestIndex = nextGreatestIndex + 1;
 
            hm.remove(currentGreatestValue);
        }

        return mostOccuredValues;
    }
}

错误原因

  • 迭代器耗尽:仅初始化一次hmIterator,第一次循环遍历完后,迭代器已走到末尾,后续循环中while (hmIterator.hasNext())不会执行,currentGreatestValue保留上一次的值。当该值已被移除后,hm.get(currentGreatestValue)返回null,赋值给int类型数组时触发空指针异常。
  • 核心逻辑偏离题目要求:当前代码是比较键的数值大小,而题目需要的是按元素出现频率(HashMap的值)取前k个元素,即便解决空指针问题,结果也不符合题目要求。
  • 直接修改HashMap的潜在风险:在迭代器遍历后直接调用hm.remove(),若后续复用同一迭代器,会触发ConcurrentModificationException,不过这里的问题先出在迭代器耗尽。

修复方案

方案1:按频率排序(推荐,符合题目要求)

先统计元素频率,再将键值对按频率降序排序,取前k个键即可:

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        HashMap<Integer, Integer> freqMap = new HashMap<>();
        // 简化频率统计逻辑
        for (int num : nums) {
            freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);
        }

        // 将entry按频率降序排序
        List<Map.Entry<Integer, Integer>> entryList = new ArrayList<>(freqMap.entrySet());
        entryList.sort((a, b) -> b.getValue() - a.getValue());

        // 提取前k个元素的键
        int[] result = new int[k];
        for (int i = 0; i < k; i++) {
            result[i] = entryList.get(i).getKey();
        }
        return result;
    }
}

方案2:迭代移除方式(满足你移除键的需求,同时修正逻辑)

每次循环前重新遍历HashMap找到当前频率最高的键,移除后再进入下一轮循环:

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        HashMap<Integer, Integer> freqMap = new HashMap<>();
        for (int num : nums) {
            freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);
        }

        int[] result = new int[k];
        int index = 0;

        for (int i = 0; i < k; i++) {
            int maxFreq = -1;
            Integer targetKey = null;
            // 每次循环重新遍历找频率最高的键
            for (Map.Entry<Integer, Integer> entry : freqMap.entrySet()) {
                if (entry.getValue() > maxFreq) {
                    maxFreq = entry.getValue();
                    targetKey = entry.getKey();
                }
            }
            // 存入结果并移除该键
            result[index++] = targetKey;
            freqMap.remove(targetKey);
        }

        return result;
    }
}

内容的提问来源于stack exchange,提问作者user883311

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 05:38:15