为何向队列添加元素后仍为空?Java医院分诊程序故障排查
问题分析与解决方案
核心问题:实例不共享导致队列空
你在Main方法中创建了StackUp pacientes并添加了测试患者,但GestaoHospital atender内部的empilha是另一个全新的StackUp实例,两者完全独立,所以调用atender.atenderPacientes()时,操作的是空队列,必然抛出空队列异常。
其他关键问题
- 硬编码出队操作:
empilharPacientes()中固定执行7次dequeue,不管对应队列是否有足够元素,只要某个队列元素不足,就会触发空队列异常。 - Scanner输入异常:
registrarPaciente()中使用nextInt()后未处理换行符,后续nextLine()会读取到空字符串,导致患者姓名录入错误。 - 栈的使用逻辑:栈是后进先出结构,按你的压栈顺序,出栈时会和预期的处理顺序相反,需要确认是否符合业务需求。
修复后的代码实现
1. 修正StackUp类:处理空队列,避免硬编码
import java.util.Stack; import java.util.Queue; // 若使用自定义Queue需确保实现isEmpty方法,否则替换为java.util.LinkedList public class StackUp { private Queue<Patient> listLeve = new Queue<>(); private Queue<Patient> listNormal = new Queue<>(); private Queue<Patient> listModerado = new Queue<>(); private Queue<Patient> listSevero = new Queue<>(); public void addPacientesFila(Patient x) throws Exception{ if (x.getPrioridade() == 0) { listLeve.enqueue(x); } else if (x.getPrioridade() == 1) { listNormal.enqueue(x); } else if (x.getPrioridade() == 2) { listModerado.enqueue(x); } else if (x.getPrioridade() == 3) { listSevero.enqueue(x); } else { throw new Exception("Número de prioridade errado"); } } public Stack<Patient> empilharPacientes() { Stack<Patient> pilha = new Stack<>(); // 队列非空时才执行出队压栈操作 if (!listNormal.isEmpty()) pilha.push(listNormal.dequeue()); if (!listSevero.isEmpty()) pilha.push(listSevero.dequeue()); if (!listModerado.isEmpty()) pilha.push(listModerado.dequeue()); if (!listSevero.isEmpty()) pilha.push(listSevero.dequeue()); if (!listLeve.isEmpty()) pilha.push(listLeve.dequeue()); if (!listModerado.isEmpty()) pilha.push(listModerado.dequeue()); if (!listSevero.isEmpty()) pilha.push(listSevero.dequeue()); return pilha; } }
2. 修正GestaoHospital类:共享StackUp实例,修复Scanner问题
import java.util.Scanner; import java.util.List; import java.util.ArrayList; import java.util.Stack; public class GestaoHospital { Scanner scanner = new Scanner(System.in); private StackUp empilha; // 通过构造函数传入外部StackUp实例,实现数据共享 public GestaoHospital(StackUp empilha) { this.empilha = empilha; } public void registrarPaciente() throws Exception { System.out.println("Informe o nome do paciente: "); String nome = scanner.nextLine(); System.out.println("Digite o cpf do paciente: "); int cpf = scanner.nextInt(); scanner.nextLine(); // 处理nextInt遗留的换行符 System.out.println("Informe o nível de prioridade do paciente: "); int prioridade = scanner.nextInt(); scanner.nextLine(); // 处理换行符 Patient pessoa = new Patient(nome, cpf, prioridade); empilha.addPacientesFila(pessoa); } public void atenderPacientes() { Stack<Patient> pilha = empilha.empilharPacientes(); List<Patient> lista = new ArrayList<>(); // 手动实现栈的全弹出逻辑(Java标准Stack无popAll方法) while (!pilha.isEmpty()) { lista.add(pilha.pop()); } for(Patient paciente : lista) { System.out.println("O paciente " + paciente.getNome() + " de CPF " + paciente.getCpf() + " foi atendido com o nível de prioridade " + paciente.getPrioridade()); System.out.println("Pressione <ENTER> para atender o próximo paciente..."); scanner.nextLine(); } } }
3. 修正Main类:传递StackUp实例给GestaoHospital
import java.util.Random; public class Main { public static void main(String[] args) throws Exception { Random random = new Random(); StackUp pacientes = new StackUp(); // 传入同一个StackUp实例,确保数据共享 GestaoHospital atender = new GestaoHospital(pacientes); for(int i = 0; i < 10; i++) { int numeroAleatorio = random.nextInt(4); Patient exemplo = new Patient("Zé", i, numeroAleatorio); pacientes.addPacientesFila(exemplo); } atender.atenderPacientes(); } }
补充说明
- 若你的
Queue是自定义类,需确保它实现了isEmpty()方法,否则可以直接替换为Java标准库的java.util.LinkedList(它实现了Queue接口)。 - 栈的后进先出特性会导致压栈顺序和出栈处理顺序相反,比如先压入的普通患者会最后被处理,若需要按压栈顺序处理,建议改用队列,或者调整压栈顺序。
内容的提问来源于stack exchange,提问作者Deivid Oliveira
相关产品推荐
相关产品推荐

