自定义HashMap扩容时触发NullPointerException问题求助
问题原因分析及解决建议
你的NullPointerException根源是自定义HashMap的扩容copy方法存在逻辑漏洞,和IDE无关——NetBeans没报错只是测试场景刚好没触发这个漏洞,具体可能的原因如下:
未处理旧数组中的空桶
你的HashMap采用链表法处理哈希冲突(每个数组元素是一个List<Pair<K,V>>),但在copy方法遍历旧数组时,没有判断当前桶(this.array[index])是否为null,直接调用size()方法。旧数组中必然存在大量未被使用的空桶(默认值为null),当遍历到这些位置时,就会触发NPE。NetBeans中可能你的测试数据刚好填满了旧数组的所有桶,没走到空桶的分支,所以没暴露问题。新数组桶未提前初始化
扩容创建新数组后,没有为每个桶提前实例化空的List对象。当尝试将旧元素转移到新数组的对应位置时,如果代码先调用了该位置List的size()(比如统计元素数量或判断冲突),就会因为List为null抛出异常。
修复示例
针对第一种情况,在遍历旧数组时增加null判断:
private void copy(List<Pair<K,V>>[] oldArray) { for (int i = 0; i < oldArray.length; i++) { List<Pair<K,V>> bucket = oldArray[i]; if (bucket == null) { continue; // 跳过空桶,避免调用null对象的方法 } // 处理桶内元素的转移逻辑 for (Pair<K,V> pair : bucket) { int newIndex = hash(pair.getKey()) % this.array.length; this.array[newIndex].add(pair); } } }
如果是第二种情况,创建新数组时初始化每个桶:
private void resize() { int newCapacity = this.array.length * 2; List<Pair<K,V>>[] newArray = new List[newCapacity]; // 初始化每个桶为空List for (int i = 0; i < newCapacity; i++) { newArray[i] = new YourCustomList<>(); } List<Pair<K,V>>[] oldArray = this.array; this.array = newArray; copy(oldArray); }
内容的提问来源于stack exchange,提问作者crawwwler
相关产品推荐
相关产品推荐

