如何在含空元素的对象数组条件判断中规避NullPointerException
问题说明
我有一个固定大小为4的Patient对象数组ExamRoom,无患者时数组内对应元素为空。Patient类包含String类型的name属性和int类型的waitTime属性。
程序要实现两个核心功能:
- CheckIn:接收用户输入的姓名,将患者添加到
ExamRoom数组,数组满则放入等待队列 - CheckOut:接收姓名,把输入姓名转大写后和数组中患者的
name(大写)对比,完成退房操作
目前CheckIn通过countNames计数器能正常工作,但CheckOut里执行ExamRoom[i].name == n.toUpperCase()时会触发NullPointerException。加try/catch只能避免崩溃,没解决根本问题,而且要求不能用ArrayList这类灵活集合,必须基于数组实现。
相关代码
Patient类
public class Patient { public String name; public int waitTime; Patient(String name, int waitTime) { this.name = name; this.waitTime = waitTime; } }
主菜单调用代码
final int NumRm = 4; int WaitTime = -1; Patient[] ExamRoom = new Patient[NumRm]; Queue<Patient> WaitingRoom = new LinkedList<Patient>(); switch (choice) { case -1: break; case 1: System.out.println("Check in:"); System.out.println("---------"); System.out.println("Enter the name of the patient you would like to check in."); String InPatientName = kbReader.nextLine(); Doctors_Office.CheckIn(InPatientName, WaitTime, ExamRoom, WaitingRoom); break; case 2: System.out.println("Check out:"); System.out.println("----------"); System.out.println("Enter the name of the person you would like to check out."); String OutPatientName = kbReader.nextLine(); Doctors_Office.CheckOut(OutPatientName, WaitTime, ExamRoom, WaitingRoom); break; }
Doctors_Office类(含CheckIn/CheckOut)
public class Doctors_Office { static int i,j,k,l; static int EmptyExmRoom; static Boolean ExamRmFull; static Boolean ExamRmEmpty; static Boolean WaitingRmEmpty; static int countNames = 0; static int comb = 5; int waitTime; String name; public Doctors_Office(String name, int waitTime, Patient[] ExamRoom, Queue<Patient> WaitingRoom) { this.waitTime = waitTime; this.name = name; } public static void CheckIn (String n, int wt, Patient[] ExamRoom, Queue<Patient> WaitingRoom) { if (countNames < ExamRoom.length) { int RmNmbr = countNames + 1; wt = 0; ExamRoom[countNames] = new Patient(n.toUpperCase(), wt); countNames += 1; System.out.println("The Patient was checked into Exam Room number " + RmNmbr + "."); System.out.println(ExamRoom[countNames - 1].name + " bloop " + ExamRoom[countNames - 1].waitTime); } else if (countNames >= ExamRoom.length) { wt = comb; WaitingRoom.add(new Patient(n.toUpperCase(),wt)); System.out.println("The Exam Rooms are currently full. Patient was sent to the Waiting Room."); System.out.println(WaitingRoom.peek().name + " has a wait time of " + WaitingRoom.peek().waitTime + " minutes."); countNames += 1; comb += 5; } } public static void CheckOut (String n, int wt, Patient[] ExamRoom, Queue<Patient> WaitingRoom) { int PatientExmRm; int index; int position; if (countNames == 0) { System.out.println("There are not any Patients in the Exam Room to check out."); } else if (countNames != 0) { try { for(i = 0; i < ExamRoom.length; i++) { System.out.println("bloop1"); if (ExamRoom[i].name == n.toUpperCase()) { System.out.println("bloop2"); PatientExmRm = i +1; index = i; Patient[] Copy = new Patient[ExamRoom.length - 1]; for (j = 0, k = 0; j < ExamRoom.length; j++) { System.out.println("bloop3"); if (j == index) { System.out.println("bloop4"); continue; } Copy[k++] = ExamRoom[j]; ExamRoom = Copy; countNames -= 1; } System.out.println("The Patient " + n + " was sucessfully checked out of Exam Room " + PatientExmRm + "."); if (WaitingRoom.isEmpty() == true) { System.out.println("There are not any Patients in the Waiting Room at this time"); } else if (WaitingRoom.isEmpty() == false) { position = index; String QueuedPatient = WaitingRoom.peek().name; Patient[] New = new Patient[ExamRoom.length + 1]; for (l = 0; l < ExamRoom.length + 1; l++) { if (l < position - 1) { New[l] = ExamRoom[l]; } else if (l == position - 1) { New[l] = WaitingRoom.peek(); New[l] = WaitingRoom.remove(); New[l] = Patient(WaitingRoom.peek().name, WaitingRoom.peek().waitTime); } else { New[l] = ExamRoom[l - 1]; } } System.out.println("The Patient " + QueuedPatient + " was moved from the Waiting Room to Exam Room number " + PatientExmRm + "."); } break; } else { System.out.println("The patient you are looking for is not in an Exam Room."); } } }catch (NullPointerException e) { System.out.println(e); } } } }
问题修复方案
1. 解决NullPointerException的核心
空指针的直接原因是遍历数组时,没先判断ExamRoom[i]是否为null就直接访问name属性。另外,字符串比较不能用==(比较对象引用),必须用equals()(比较字符串内容)。
修改判断逻辑:
if (ExamRoom[i] != null && ExamRoom[i].name.equals(n.toUpperCase()))
2. 修正CheckOut的数组操作逻辑
原代码错误地修改了数组长度(题目要求数组大小固定为4),而且复制数组时提前替换原数组导致逻辑混乱。正确的做法是保持数组大小不变,将空诊室的位置设为null,后续直接复用该位置。
修正后的CheckOut方法:
public static void CheckOut(String n, int wt, Patient[] ExamRoom, Queue<Patient> WaitingRoom) { String targetName = n.toUpperCase(); int targetIndex = -1; // 遍历数组找到目标患者的索引 for (int i = 0; i < ExamRoom.length; i++) { if (ExamRoom[i] != null && ExamRoom[i].name.equals(targetName)) { targetIndex = i; break; } } // 没找到患者的情况 if (targetIndex == -1) { System.out.println("目标患者不在诊室中。"); return; } // 执行退房:将该位置设为空 int roomNumber = targetIndex + 1; System.out.println("患者 " + n + " 已成功从诊室" + roomNumber + "退房。"); ExamRoom[targetIndex] = null; countNames--; // 从等待队列转移患者到空诊室 if (!WaitingRoom.isEmpty()) { Patient nextPatient = WaitingRoom.poll(); ExamRoom[targetIndex] = nextPatient; countNames++; System.out.println("等待队列中的患者 " + nextPatient.name + " 已转移到诊室" + roomNumber + "。"); } else { System.out.println("当前等待队列中没有患者。"); } }
3. 其他优化点
- 移除
Doctors_Office中不必要的静态变量(如i,j,k,l),改用方法内的局部变量,避免多线程下的安全问题。 CheckIn中的countNames计数逻辑需要调整:当从等待队列转移患者到诊室时,countNames要加1(原代码只有CheckIn时加,会导致计数错误)。- 统一用
equals()或equalsIgnoreCase()做字符串比较,避免大小写和引用比较的问题。
内容的提问来源于stack exchange,提问作者Mando0110
相关产品推荐
相关产品推荐

