Implementación de un Sistema de Gestión de Residencias Estudiantiles en Java

El desarrollo de sistemas de gestión para entornos educativos es fundamental para optimizar la administración de recursos. En el contexto universitario, la gestión eficiente de dormitorios o residencias estudiantiles es una tarea clave que puede beneficiarse enormemente de una solución de software. Este artículo presenta un sistema básico de gestión de residencias estudiantiles implementado en Java, que permite realizar operaciones como la consulta del estado de las habitaciones, la asignación de estudiantes, la evaluación de higiene y la generación de informes.

El sistema está estructurado en dos clases principales: Dormitorio, que modela la información de cada habitación, y SistemaGestionDormitorios, que contiene la lógica de negocio y la interfaz de usuario basada en consola.

Diseño de la Clase Dormitorio

La clase Dormitorio encapsula los atributos de una habitación, como su número, la lista de estudiantes asignados y una puntuación de higiene. Se ha optado por una lista dinámica para los identificadores de los estudiantes, lo que proporciona mayor flexibilidad y escalabilidad que un número fijo de campos individuales. También incluye métodos para gestionar la ocupación y el estado de la habitación.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class Dormitorio {
   private String numeroHabitacion;
   private List<String> idsEstudiantes;
   private int puntuacionHigiene;
   private final int CAPACIDAD_MAXIMA = 4; // Capacidad máxima de estudiantes por habitación

   /**
    * Constructor para inicializar un dormitorio con una lista de IDs de estudiantes.
    * Los IDs vacíos o nulos son filtrados automáticamente.
    */
   public Dormitorio(String numeroHabitacion, List<String> idsIniciales, int puntuacionHigiene) {
       this.numeroHabitacion = numeroHabitacion;
       this.idsEstudiantes = idsIniciales.stream()
                                         .filter(s -> s != null && !s.trim().isEmpty())
                                         .collect(Collectors.toList());
       this.puntuacionHigiene = puntuacionHigiene;
   }

   // Getters
   public String getNumeroHabitacion() { return numeroHabitacion; }
   public List<String> getIdsEstudiantes() { return new ArrayList<>(idsEstudiantes); } // Retorna copia defensiva
   public int getPuntuacionHigiene() { return puntuacionHigiene; }
   public int getOcupacionActual() { return idsEstudiantes.size(); }
   public int getCapacidadRestante() { return CAPACIDAD_MAXIMA - idsEstudiantes.size(); }

   // Setters
   public void setPuntuacionHigiene(int puntuacionHigiene) { this.puntuacionHigiene = puntuacionHigiene; }

   /**
    * Verifica si el dormitorio está completamente lleno.
    * @return true si el dormitorio está lleno, false en caso contrario.
    */
   public boolean estaLleno() { return idsEstudiantes.size() == CAPACIDAD_MAXIMA; }

   /**
    * Verifica si el dormitorio está completamente vacío.
    * @return true si el dormitorio está vacío, false en caso contrario.
    */
   public boolean estaVacio() { return idsEstudiantes.isEmpty(); }

   /**
    * Intenta agregar un estudiante al dormitorio.
    * @param idEstudiante El ID del estudiante a agregar.
    * @return true si el estudiante fue agregado exitosamente, false si el dormitorio está lleno
    *         o el estudiante ya está asignado a esta habitación.
    */
   public boolean agregarEstudiante(String idEstudiante) {
       if (idEstudiante == null || idEstudiante.trim().isEmpty()) {
           return false; // No se permiten IDs vacíos
       }
       if (idsEstudiantes.size() < CAPACIDAD_MAXIMA && !idsEstudiantes.contains(idEstudiante)) {
           idsEstudiantes.add(idEstudiante);
           return true;
       }
       return false;
   }
   
   /**
    * Intenta eliminar un estudiante del dormitorio.
    * @param idEstudiante El ID del estudiante a eliminar.
    * @return true si el estudiante fue eliminado, false si no se encontró en esta habitación.
    */
   public boolean eliminarEstudiante(String idEstudiante) {
       return idsEstudiantes.remove(idEstudiante);
   }
   
   /**
    * Retorna una descripción del estado de ocupación del dormitorio.
    * @return Cadena que describe la ocupación (ej. "Completo (4/4)", "Vacío", "Ocupado (2/4, 2 libres)").
    */
   public String getEstadoOcupacion() {
       int ocupacion = getOcupacionActual();
       if (ocupacion == CAPACIDAD_MAXIMA) {
           return "Completo (" + ocupacion + "/" + CAPACIDAD_MAXIMA + ")";
       } else if (ocupacion == 0) {
           return "Vacío";
       } else {
           return "Ocupado (" + ocupacion + "/" + CAPACIDAD_MAXIMA + ", " + getCapacidadRestante() + " libres)";
       }
   }
}

Clase Principal: SistemaGestionDormitorios

La clase SistemaGestionDormitorios es el punto de entrada de la aplicación. Gestiona una colección de objetos Dormitorio y proporciona métodos para interactuar con el usuario a través de un menú de consola. Incluye funcionalidades para mostrar el estado de los dromitorios, asignar estudiantes a habitaciones vacías, añadir estudiantes a habitaciones con plazas disponibles, registrar las puntuaciones de higiene y generar un informe de inspección.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;

public class SistemaGestionDormitorios {
   private static Scanner lectorEntrada = new Scanner(System.in);
   private static List<Dormitorio> listaDormitorios = new ArrayList<>();

   /**
    * Método auxiliar para filtrar IDs de estudiantes vacíos o nulos de un array.
    * @param ids Arreglo de IDs de estudiantes.
    * @return Lista de IDs de estudiantes válidos.
    */
   private static List<String> filtrarEstudiantes(String... ids) {
       return Arrays.stream(ids)
                    .filter(s -> s != null && !s.trim().isEmpty())
                    .collect(Collectors.toList());
   }

   public static void main(String[] args) {
       // Inicialización de datos de ejemplo para los dormitorios
       listaDormitorios.add(new Dormitorio("9#101", filtrarEstudiantes("20210001", "20210002", "20210003", "20210004"), 0));
       listaDormitorios.add(new Dormitorio("9#102", filtrarEstudiantes("20210011", "20210012", "20210013", "20210014"), 0));
       listaDormitorios.add(new Dormitorio("9#103", filtrarEstudiantes("20210021", "20210022", "20210023"), 0));
       listaDormitorios.add(new Dormitorio("9#104", filtrarEstudiantes("20210031", "20210032", "20210033"), 0));
       listaDormitorios.add(new Dormitorio("9#105", filtrarEstudiantes("20210041"), 0));
       listaDormitorios.add(new Dormitorio("9#106", filtrarEstudiantes("20210051", "20210052", "20210053", "20210054"), 0));
       // Dormitorios vacíos para nuevas asignaciones
       listaDormitorios.add(new Dormitorio("9#107", filtrarEstudiantes(), 0));
       listaDormitorios.add(new Dormitorio("9#108", filtrarEstudiantes(), 0));
       listaDormitorios.add(new Dormitorio("9#109", filtrarEstudiantes(), 0));
       listaDormitorios.add(new Dormitorio("9#110", filtrarEstudiantes(), 0));
       
       // Bucle principal de la aplicación
       while (true) {
           mostrarMenuPrincipal();
           int opcion = -1;
           try {
               opcion = lectorEntrada.nextInt();
               lectorEntrada.nextLine(); // Consumir el salto de línea pendiente
           } catch (InputMismatchException e) {
               System.out.println("Entrada inválida. Por favor, ingrese un número.");
               lectorEntrada.nextLine(); // Consumir la entrada inválida
               continue;
           }

           switch (opcion) {
               case 1:
                   mostrarEstadoDormitorios();
                   break;
               case 2:
                   asignarEstudianteANuevoDormitorio();
                   break;
               case 3:
                   realizarAjusteDormitorio();
                   break;
               case 4:
                   registrarPuntuacionHigiene();
                   break;
               case 5:
                   reporteInspeccionHigiene();
                   break;
               case 0:
                   System.out.println("Saliendo del sistema. ¡Hasta pronto!");
                   return;
               default:
                   System.out.println("Opción no válida. Por favor, seleccione una opción del menú.");
           }
           System.out.println("\nPresione Enter para continuar...");
           lectorEntrada.nextLine(); // Esperar a que el usuario presione Enter
       }
   }

   /**
    * Muestra el encabezado del sistema y el menú principal.
    */
   private static void mostrarMenuPrincipal() {
       System.out.println("***********************************************************");
       System.out.println("\t\tUNIVERSIDAD DE SHIJIAZHUANG TIEDAO");
       System.out.println("\t\tSistema de Gestión de Residencias Estudiantiles v2024");
       System.out.println("***********************************************************");
       System.out.println("\t\tMenú Principal:");
       System.out.println("\t\t1. Consultar estado de dormitorios");
       System.out.println("\t\t2. Asignar estudiante a dormitorio vacío");
       System.out.println("\t\t3. Añadir estudiante a dormitorio existente");
       System.out.println("\t\t4. Registrar puntuación de higiene");
       System.out.println("\t\t5. Ver informe de higiene");
       System.out.println("\t\t0. Salir");
       System.out.println("***********************************************************");
       System.out.print("Ingrese su opción: ");
   }
   
   /**
    * Busca un dormitorio por su número de habitación.
    * @param numero El número de la habitación a buscar.
    * @return El objeto Dormitorio si se encuentra, o null en caso contrario.
    */
   private static Dormitorio buscarDormitorio(String numero) {
       for (Dormitorio dorm : listaDormitorios) {
           if (dorm.getNumeroHabitacion().equals(numero)) {
               return dorm;
           }
       }
       return null;
   }

   /**
    * Verifica si un ID de estudiante ya está asignado a algún dormitorio.
    * @param idEstudiante El ID del estudiante a verificar.
    * @return true si el estudiante ya está asignado, false en caso contrario.
    */
   private static boolean estudianteYaAsignado(String idEstudiante) {
       for (Dormitorio dorm : listaDormitorios) {
           if (dorm.getIdsEstudiantes().contains(idEstudiante)) {
               return true;
           }
       }
       return false;
   }

   /**
    * Muestra una lista detallada del estado actual de todos los dormitorios.
    */
   private static void mostrarEstadoDormitorios() {
       System.out.println("\n--- Estado Detallado de Dormitorios ---");
       if (listaDormitorios.isEmpty()) {
           System.out.println("No hay dormitorios registrados en el sistema.");
           return;
       }
       for (int i = 0; i < listaDormitorios.size(); i++) {
           Dormitorio dorm = listaDormitorios.get(i);
           System.out.printf("%d. %s - %s%n", (i + 1), dorm.getNumeroHabitacion(), dorm.getEstadoOcupacion());
           if (!dorm.getIdsEstudiantes().isEmpty()) {
               System.out.print("   Estudiantes: ");
               System.out.println(String.join(", ", dorm.getIdsEstudiantes()));
           }
       }
       System.out.println("----------------------------------------");
   }

   /**
    * Permite asignar estudiantes a dormitorios que están completamente vacíos.
    */
   private static void asignarEstudianteANuevoDormitorio() {
       System.out.println("\n--- Asignar Estudiante a Dormitorio Vacío ---");
       List<Dormitorio> dormitoriosVacios = listaDormitorios.stream()
                                                           .filter(Dormitorio::estaVacio)
                                                           .collect(Collectors.toList());

       if (dormitoriosVacios.isEmpty()) {
           System.out.println("No hay dormitorios completamente vacíos disponibles para nuevas asignaciones.");
           return;
       }

       System.out.println("Dormitorios vacíos disponibles:");
       for (int i = 0; i < dormitoriosVacios.size(); i++) {
           System.out.printf("%d. %s%n", (i + 1), dormitoriosVacios.get(i).getNumeroHabitacion());
       }

       System.out.print("Ingrese el número del dormitorio para asignar: ");
       String numDormitorio = lectorEntrada.nextLine();
       Dormitorio dormSeleccionado = buscarDormitorio(numDormitorio);

       if (dormSeleccionado == null) {
           System.out.println("El dormitorio ingresado no existe.");
           return;
       }
       if (!dormSeleccionado.estaVacio()) {
           System.out.println("El dormitorio " + dormSeleccionado.getNumeroHabitacion() + " no está completamente vacío. Use la opción 3 para añadir estudiantes a dormitorios existentes.");
           return;
       }
       
       System.out.println("Asignando estudiantes al dormitorio " + dormSeleccionado.getNumeroHabitacion());
       while (!dormSeleccionado.estaLleno()) {
           System.out.printf("Ingrese ID de estudiante para cama %d (o 'FIN' para terminar): ", dormSeleccionado.getOcupacionActual() + 1);
           String idEstudiante = lectorEntrada.nextLine().trim();
           if (idEstudiante.equalsIgnoreCase("FIN")) {
               break;
           }
           if (idEstudiante.isEmpty()) {
               System.out.println("El ID del estudiante no puede estar vacío.");
               continue;
           }

           if (estudianteYaAsignado(idEstudiante)) {
               System.out.println("ERROR: El estudiante " + idEstudiante + " ya está asignado a otro dormitorio.");
               continue;
           }

           if (dormSeleccionado.agregarEstudiante(idEstudiante)) {
               System.out.println("Estudiante " + idEstudiante + " asignado correctamente.");
           } else {
               System.out.println("No se pudo asignar al estudiante. El dormitorio puede estar lleno o el estudiante ya está en esta habitación.");
               break; 
           }
       }
       if (dormSeleccionado.estaLleno()) {
           System.out.println("El dormitorio " + dormSeleccionado.getNumeroHabitacion() + " ha alcanzado su capacidad máxima.");
       }
   }

   /**
    * Permite añadir estudiantes a dormitorios que tienen camas disponibles.
    */
   private static void realizarAjusteDormitorio() {
       System.out.println("\n--- Añadir Estudiante a Dormitorio Existente (con espacio) ---");
       List<Dormitorio> dormitoriosConEspacio = listaDormitorios.stream()
                                                               .filter(d -> !d.estaLleno())
                                                               .collect(Collectors.toList());

       if (dormitoriosConEspacio.isEmpty()) {
           System.out.println("No hay dormitorios con camas disponibles para añadir estudiantes.");
           return;
       }

       System.out.println("Dormitorios con espacio disponible:");
       for (int i = 0; i < dormitoriosConEspacio.size(); i++) {
           Dormitorio dorm = dormitoriosConEspacio.get(i);
           System.out.printf("%d. %s (%d camas libres)%n", (i + 1), dorm.getNumeroHabitacion(), dorm.getCapacidadRestante());
       }

       System.out.print("Ingrese el número del dormitorio para añadir estudiantes: ");
       String numDormitorio = lectorEntrada.nextLine();
       Dormitorio dormSeleccionado = buscarDormitorio(numDormitorio);

       if (dormSeleccionado == null) {
           System.out.println("El dormitorio ingresado no existe.");
           return;
       }
       if (dormSeleccionado.estaLleno()) {
           System.out.println("El dormitorio " + dormSeleccionado.getNumeroHabitacion() + " ya está lleno.");
           return;
       }

       System.out.println("Añadiendo estudiantes al dormitorio " + dormSeleccionado.getNumeroHabitacion());
       System.out.println("Estudiantes actuales: " + (dormSeleccionado.getIdsEstudiantes().isEmpty() ? "Ninguno" : String.join(", ", dormSeleccionado.getIdsEstudiantes())));

       while (!dormSeleccionado.estaLleno()) {
           System.out.printf("Ingrese ID de estudiante para cama %d (o 'FIN' para terminar): ", dormSeleccionado.getOcupacionActual() + 1);
           String idEstudiante = lectorEntrada.nextLine().trim();
           if (idEstudiante.equalsIgnoreCase("FIN")) {
               break;
           }
           if (idEstudiante.isEmpty()) {
               System.out.println("El ID del estudiante no puede estar vacío.");
               continue;
           }

           if (estudianteYaAsignado(idEstudiante)) {
               System.out.println("ERROR: El estudiante " + idEstudiante + " ya está asignado a otro dormitorio.");
               continue;
           }
           
           if (dormSeleccionado.agregarEstudiante(idEstudiante)) {
               System.out.println("Estudiante " + idEstudiante + " añadido correctamente.");
           } else {
               System.out.println("No se pudo añadir al estudiante. El dormitorio está lleno o el estudiante ya está en esta habitación.");
               break;
           }
       }
       if (dormSeleccionado.estaLleno()) {
           System.out.println("El dormitorio " + dormSeleccionado.getNumeroHabitacion() + " ha alcanzado su capacidad máxima.");
       }
   }

   /**
    * Permite registrar la puntuación de higiene para un dormitorio específico.
    */
   private static void registrarPuntuacionHigiene() {
       System.out.println("\n--- Registrar Puntuación de Higiene ---");
       System.out.print("Ingrese el número del dormitorio a evaluar: ");
       String numDormitorio = lectorEntrada.nextLine();
       Dormitorio dorm = buscarDormitorio(numDormitorio);

       if (dorm == null) {
           System.out.println("Dormitorio no encontrado.");
           return;
       }
       if (dorm.estaVacio()) {
           System.out.println("Este dormitorio está vacío, no es posible evaluar la higiene.");
           return;
       }

       System.out.println("Evaluando higiene para el dormitorio " + dorm.getNumeroHabitacion());
       System.out.println("Estudiantes actuales: " + String.join(", ", dorm.getIdsEstudiantes()));
       System.out.print("Ingrese la puntuación de higiene (0-100): ");
       int score;
       while (true) {
           try {
               score = lectorEntrada.nextInt();
               lectorEntrada.nextLine(); // Consumir el salto de línea pendiente
               if (score >= 0 && score <= 100) {
                   dorm.setPuntuacionHigiene(score);
                   System.out.println("Puntuación de higiene de " + score + " registrada para el dormitorio " + dorm.getNumeroHabitacion());
                   break;
               } else {
                   System.out.print("Puntuación inválida. Por favor, ingrese un número entre 0 y 100: ");
               }
           } catch (InputMismatchException e) {
               System.out.print("Entrada inválida. Por favor, ingrese un número entero: ");
               lectorEntrada.nextLine(); // Consumir la entrada inválida
           }
       }
   }

   /**
    * Genera y muestra un informe de las puntuaciones de higiene de todos los dormitorios.
    */
   private static void reporteInspeccionHigiene() {
       System.out.println("\n--- Informe de Inspección de Higiene ---");
       if (listaDormitorios.isEmpty()) {
           System.out.println("No hay dormitorios registrados para generar el informe.");
           return;
       }
       for (int i = 0; i < listaDormitorios.size(); i++) {
           Dormitorio dorm = listaDormitorios.get(i);
           String calificacion;
           // Manejo de casos para dormitorios vacíos o no evaluados
           if (dorm.estaVacio()) {
               calificacion = "Dormitorio vacío";
           } else if (dorm.getPuntuacionHigiene() == 0) { // Si la puntuación es 0 y no está vacío, asumimos "no evaluado"
               calificacion = "No evaluado / Deficiente";
           } else if (dorm.getPuntuacionHigiene() < 60) {
               calificacion = "No apto";
           } else if (dorm.getPuntuacionHigiene() < 80) {
               calificacion = "Aceptable";
           } else if (dorm.getPuntuacionHigiene() < 90) {
               calificacion = "Bueno";
           } else { // 90-100
               calificacion = "Excelente";
           }
           System.out.printf("%d. Dormitorio %s: %d puntos (%s)%n", (i + 1), dorm.getNumeroHabitacion(), dorm.getPuntuacionHigiene(), calificacion);
       }
       System.out.println("----------------------------------------");
   }
}

Etiquetas: java Gestión de Residencias POO CLI ArrayList

Publicado el 7-31 03:26