You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在含空元素的对象数组条件判断中规避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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 15:24:53