Se tienen N asignaturas, codificadas con tres números, y M alumnos, cada uno de ellos con el primer y segundo apellido, el nombre y uno o varios códigos de asignaturas. Construir las Estructuras de datos y los algoritmos necesarios para almacenar esta información y diseñar un método que nos muestre los datos personales de cada alumno y el nombre de todas las asignaturas en que esté matriculado.
Pues bien, uno de vosotros me ha mandado esta posible solución, de la que indicaré unas mejoras más abajo:
import java.io.IOException; import java.util.*; import listas.*;import utilidades.*;
public class ej2 {
static class Alumno {
private String nombre, apellido1, apellido2, dni;
private Listaasignaturas;
public Alumno(String n, String ap1, String ap2, String d){
nombre=n;
apellido1=ap1;
apellido2=ap2;
dni=d;
}
@Override public int hashCode(){
return dni.hashCode();
}
@Override public boolean equals(Object o){
return o instanceof Alumno && dni.equals(((Alumno) o).dni);
}
@Override public String toString(){
return dni+" "+nombre+" "+apellido1+" "+apellido2;
}
}
static Hashtable<> asignaturas = new Hashtable<> ();
static Hashtable<>> alumnos = new Hashtable<>> ();
public static void main(String aaa[]) throws IOException{
String textomenu=" 1.- Añadir asignatura 2.- Añadir alumno 3.- Mostrar 0.- Salir";
boolean fin=false;
do{
int elec=leer.entero(textomenu);
try{
switch (elec){
case 1:
añadirAsignatura(); break;
case 2:
añadirAlumno(); break;
case 3:
mostrar(); break;
case 0:
fin=true; break;
}//switch
}//try
catch(Exception e){ System.err.println(e.getMessage()); }
}while(!(fin));
}
private static void añadirAsignatura() throws IOException {
boolean seguir =true;
while(seguir){
Integer codigo=leer.entero("Dame el codigo de la asignatura");
String nombre = leer.cadena("Dame el nombre");
if(!asignaturas.containsKey(codigo)){
asignaturas.put(codigo, nombre);
}else System.out.println("Ya existe una asignatura con ese código");
char c = leer.caracter("¿Alguna asignatua más? s/n");
if(c=='n')
seguir=false;
}
}
@SuppressWarnings("element-type-mismatch")
private static void añadirAlumno() throws IOException {
boolean seguir =true;
while(seguir){
String nombre=leer.cadena("Dame el nombre del alumno");
String ap1 = leer.cadena("Primer apellido");
String ap2 = leer.cadena("Segundo apellido");
String dni= leer.cadena("DNI");
if(!alumnos.containsKey(dni)){
Alumno nuevo = new Alumno(nombre, ap1, ap2,dni);
Listaasig = new Lista ();
boolean seg=true;
while(seg){
Integer cod = leer.entero("Dame el codigo de la asignatura");
if(!asignaturas.containsKey(cod))
System.out.println("Esa asignatura no pertenece a la tabla");
else
asig.insertarFinal(cod);
char c = leer.caracter("¿Alguna asignatura más? s/n");
if(c=='n')
seg=false;
}
alumnos.put(nuevo, asig);
}
char c = leer.caracter("¿Algún alumno más? s/n");
if(c=='n')
seguir=false;
}
}
private static void mostrar() {
Enumeration alums = alumnos.keys();
Enumeration asig = alumnos.elements();
while(alums.hasMoreElements()){
Alumno a = (Alumno) alums.nextElement();
Lista <> l = (Lista <>) asig.nextElement();
System.out.println(a.toString());
System.out.println("Asignaturas: ");
while(!l.esVacia()){
System.out.println(asignaturas.get(l.primero()));
l=l.resto();
}
}
}
}
Las posibles mejoras que os decía son:
- Si en la clase Alumno defines el atributo asignaturas, en la tablaalumnos las asignaturas las estás almacenando dos veces: una con el alumno, como es la clave, y otra en el valor del alumno. Puesto que esto puede generar problemas de consistencia (aparte de redundancia) propongo dos cosas:
- Una: separar lo que es la clave del alumno (datos personales) de la información (lista de asignaturas)
- Otra: eliminar el atributo asignaturas del alumno. El inconveniente de esta opción es que si se necesita trabajar luego con el objeto alumno completo, asignaturas incluidas, en otra parte del programa, no se puedes, habría que definir otra clase.
class Alumno{
class DatosPersonales{
private String nombre, apellido1, apellido2, dni; los get, set, equals y hashCode}
private DatosPersonales datos;
private Lista
//ahora ya no es necesario el método hashcode porque iría en la clase DatosPersonales
Y la tabla alumnos se definiría así:
Hashtable <> > alumnos;
2. En el método mostrar:
Si en las Enumeration se indica el valor de la clase de la colección se evita hacer luego casting.
Por ejemplo, Emuneration <> alumns=alumnos.keys();
y luego Alumno a = alums.nextElement(); (sin casting)
Enhorabuena por el exitoso blog.
ResponderEliminarMe ha encantado vuestro blog, me ha salvado del suicidio.
ResponderEliminarYa me hubiera dado a la bebida si no hubiera sido por este blog, rebueno!
ResponderEliminarLas tablas hash son un método bastante exquisito, desde la 2ª guerra mundial no se había inventado nada mejor. Salu2.
ResponderEliminarexcelente
ResponderEliminarme parece muy bien q publiquen algo q si da beneficio a algunos estudiantes sigan asi.........
ResponderEliminar