Java代码在Eclipse正常运行但在线IDE报空指针异常求排查
看起来你的代码在本地Eclipse能正常运行,但在线IDE直接炸了——根源是
Collections.max(map.values())
抛出了空指针异常,这是因为你的HashMap里混入了
null
值,而
Collections.max
在比较元素时遇到
null
就会触发这个错误。
为什么会出现null值? #
你踩了一个Scanner使用的常见坑:
同时用两个Scanner实例读取同一个
System.in
输入流
。
当你用
Scanner s
读取学生姓名后,
Scanner e
再去读取分数时,输入流的指针已经被
s
移动过了,这会导致
e.hasNext()
可能返回
false
,进而让
mark[i]
保持默认的
null
值,然后你直接把这个
null
塞进了HashMap。一旦map的values集合里有
null
,
Collections.max
就会报错——它会尝试用
compareTo
比较元素,而
null
不能和Double做比较。
另外还有个隐藏小问题:你用
==
比较Double值,这对于包装类型来说很危险——
==
比较的是对象引用,不是实际数值,比如
Double.valueOf(100.0)
和
new Double(100.0)
用
==
比较会返回
false
。
修复方案 #
这里给你调整后的代码,解决了所有问题:
import java.util.*;
import java.util.Map.Entry;
class Main{
public static void main(String args[])throws Exception{
Scanner s = new Scanner(System.in);
HashMap<String,Double> hm=new HashMap<String,Double>();
System.out.println("Enter the number of students ");
int n=s.nextInt();
s.nextLine(); // 处理nextInt后遗留的换行符
for(int i=0;i<n;i++) {
System.out.println("Enter the details of the student "+(i+1));
String name = s.nextLine();
// 只用一个Scanner读取所有输入,避免流冲突
double mark = s.nextDouble();
s.nextLine(); // 处理nextDouble后的换行符,保证下一次读取姓名正常
hm.put(name, mark);
String maxKey = getMaxEntry(hm).getKey();
System.out.println(maxKey);
public static Entry<String, Double> getMaxEntry(Map<String, Double> map){
Entry<String, Double> maxEntry = null;
// 先判断map是否为空,避免空指针
if(map.isEmpty()){
return null;
Double max = Collections.max(map.values());
for(Entry<String, Double> entry : map.entrySet()) {
Double value = entry.getValue();
// 用equals比较Double数值,替换==的引用比较
if(value != null && max.equals(value)) {
maxEntry = entry;
break; // 取第一个遇到的最大值对应的键,如需全部可移除break