基于HashTableMap的斐波那契数计算:fibCalc2空指针异常求助
嘿,我完全懂你卡在空指针异常这儿的烦躁——自定义哈希表确实容易在细节上踩坑,咱们一步步来拆解问题、排查原因。
先定位空指针的核心原因
你提到异常出现在代码最后一行,结合你给出的代码片段private static Map<Integer, Long> ansMap = new LLQHashTableMap(10...,大概率是从自定义的LLQHashTableMap中取值时返回了null,而你直接将这个null赋值给了基本类型long(因为基本类型无法接收null,会直接触发空指针异常)。
排查与修复步骤
检查
LLQHashTableMap的get方法实现
官方HashMap在找不到对应键时会返回null,但你的自定义实现可能存在以下问题:- 哈希冲突处理逻辑有漏洞(比如链表遍历中断、节点引用丢失),导致明明已经存入的键值对无法被取出;
- 键的哈希值计算错误,导致存和取时的哈希桶位置不一致,进而取不到值返回
null。
建议你单独写个小测试用例,验证LLQHashTableMap的put和get功能是否正常,比如:
LLQHashTableMap<Integer, Long> testMap = new LLQHashTableMap<>(10); testMap.put(1, 1L); testMap.put(2, 1L); System.out.println(testMap.get(1)); // 预期输出1,若返回null则说明容器实现有问题修正斐波那契逻辑中的取值判断
不管自定义容器是否有问题,在取值时都应该先判断结果是否为null,再进行后续操作,避免NPE。比如你的fibCalc2可以改成这样:private static int callCount2; private static Map<Integer, Long> ansMap = new LLQHashTableMap<>(10); public static long fibCalc2(int n) { callCount2++; // 先处理边界情况 if (n <= 2) { return 1L; } // 用包装类Long接收,避免直接赋值给基本类型触发NPE Long cachedVal = ansMap.get(n); if (cachedVal != null) { return cachedVal; } // 计算并存入缓存 long result = fibCalc2(n-1) + fibCalc2(n-2); ansMap.put(n, result); return result; }检查容器初始化参数
你初始化LLQHashTableMap时传了10作为参数,如果这个参数是初始容量,当计算较大的斐波那契数时,容器容量不足可能导致哈希冲突加剧甚至存值失败,建议先调大初始容量(比如设为100)测试是否还会出现异常。
关于你的解决方案合理性
用哈希表做记忆化优化斐波那契计算是非常合理且高效的思路——它把递归原本O(2^n)的时间复杂度降到了O(n),空间复杂度为O(n),完全是正确的优化方向,只是自定义哈希表的实现细节需要调整。
额外小建议
如果暂时不想花时间调试自定义容器,可以先改用Java官方的HashMap替换LLQHashTableMap,先验证你的斐波那契逻辑是否正常运行。如果逻辑没问题,再回头专注排查自定义哈希表的bug,这样能快速定位问题根源。
内容的提问来源于stack exchange,提问作者Elzhan Zeinulla

