实现统计高频字符串方法时遍历HashMap抛出NullPointerException的问题排查
实现统计高频字符串方法时遍历HashMap抛出NullPointerException的问题排查
嘿,我帮你找到这个NullPointerException的根源了——是第一个循环里的一个小语法失误导致的,咱们一步步拆解问题:
问题根源分析
你在更新HashMap计数的时候写了这行代码:
frequencies.replace(this.backingArray[i], frequencies.get(backingArray[i]+1));
这里的问题是你把字符串和数字做了拼接操作,而不是先获取当前计数值再加1。举个例子:如果backingArray[i]是字符串"apple",那么backingArray[i]+1会变成"apple1",这个键在你的HashMap里根本不存在,get()方法就会返回null。之后你用这个null调用replace(),相当于把对应键的值设成了null。
当你后续遍历frequencies.values()时,用int i : frequencies.values()做增强for循环,Java会自动把Integer对象拆箱成int基本类型,但如果某个值是null,拆箱操作就会直接抛出你看到的java.lang.NullPointerException。
修正后的代码(附带优化)
我不仅修复了错误,还优化了代码结构,让它更简洁可靠:
public SList commonStrings() { HashMap<String, Integer> frequencies = new HashMap<>(this.size()); // 用merge方法简化计数逻辑,避免手动判断containsKey for (String s : this.backingArray) { frequencies.merge(s, 1, Integer::sum); } // 找出最高出现频率 int highest = 0; for (int count : frequencies.values()) { if (count > highest) { highest = count; } } // 用ArrayList动态收集高频字符串,无需提前统计数量 List<String> mostCommonList = new ArrayList<>(); for (Map.Entry<String, Integer> entry : frequencies.entrySet()) { if (entry.getValue() == highest) { mostCommonList.add(entry.getKey()); } } // 转换为SList返回 return new SListArray(mostCommonList.toArray(new String[0])); }
关键优化点说明
- 用
merge()方法简化计数:frequencies.merge(s, 1, Integer::sum)会自动处理两种情况:如果键不存在,就存入1;如果键已存在,就把当前值加1。完全替代了原来的containsKey判断,减少了出错的可能。 - 改用
ArrayList收集结果:不用提前统计numOfMostCommon的数量,直接遍历HashMap收集符合条件的字符串,最后转成数组即可,代码更简洁,也避免了数组索引操作可能出现的疏漏。 - 增强for循环遍历数组:把原来的下标循环改成增强for循环,可读性更好,也减少了数组下标操作的潜在错误。
备注:内容来源于stack exchange,提问作者Mr. Mortem
相关产品推荐
相关产品推荐

