FUNDAMENTOS DE PROGRAMACIÓN B07: TRATAMIENTOS SECUENCIALES Curso: 2013/14 Versión: 1.0.4 OBJETIVOS Resolución de cuestiones que requieran un tratamiento iterativo de un agregado de datos. Uso de los esquemas de resolución de tratamientos secuenciales vistos en clase. DESCRIPCIÓN DEL PROBLEMA En el contexto del desarrollo de la aplicación para la gestión de una biblioteca, debemos implementar una serie de funcionalidades que nos permitan resolver cuestiones relacionadas con los tipos Usuario, Libro y MedioAudiovisual vistos hasta el momento. En primer lugar, es necesario incluir en nuestra aplicación el tipo Biblioteca, que aglutinará la información sobre los usuarios y los medios (libros y medios audiovisuales) ofrecidos en la biblioteca. Una biblioteca se caracteriza mediante un código único alfanumérico, formado por dos caracteres en mayúscula seguidos de cinco dígitos numéricos (por ejemplo, “AB09753”), el nombre o centro al que pertenece (ejemplo, “Biblioteca Pública Municipal ‘Miguel Delibes’”), la dirección, el teléfono y el responsable, propiedad ésta última que se modelará a través del tipo EmpleadoPublico. Además, una biblioteca posee: un archivo con el registro de todos sus usuarios (que no admite elementos duplicados), una lista con todos los ejemplares de libros que se encuentran en la biblioteca (puede haber duplicados) y otra lista con los medios audiovisuales disponibles (puede haber duplicados si hay más de un ejemplar). Una vez creada una biblioteca en el sistema, sólo el código deberá permanecer invariable durante todo el tiempo en que la biblioteca esté dada de alta en el sistema. DETALLES DE DISEÑO E IMPLEMENTACIÓN A continuación se describe esquemáticamente el diseño del tipo Biblioteca que vamos a incorporar a nuestra aplicación. Tipo Biblioteca. Propiedades: • Codigo. Propiedad básica, de tipo String. Consultable. Debe estar formado por dos caracteres en mayúsculas, seguidos de 5 dígitos. • Nombre. Propiedad básica, de tipo String. Consultable y modificable. Sin restricciones. • Direccion. Propiedad básica, de tipo String. Consultable y modificable. Sin restricciones. • Telefono. Propiedad básica, de tipo String. Consultable y modificable. Sin restricciones. • Responsable. Propiedad básica, de tipo EmpleadoPublico. Consultable y modificable. Sin restricciones. • Usuarios. Propiedad básica, de tipo Set<Usuario>. Consultable y modificable. Sin restricciones. • Libros. Propiedad básica, de tipo List<Libro>. Consultable y modificable. Sin restricciones. • Audiovisuales. Propiedad básica, de tipo List<MedioAudiovisual>. Consultable y modificable. Sin restricciones. Constructor: Recibe todas las propiedades como parámetros de entrada, a excepción de los usuarios, libros y audiovisuales que se inicializan a vacío. Criterio de igualdad: Por código. B07: Tratamientos Secuenciales 2 Criterio de orden natural: Por código. Representación como cadena: Código y nombre, separados por guion y espacios a ambos lados del mismo (ejemplo; “AB09753 - Biblioteca Pública Municipal ‘Miguel Delibes’”). Otras operaciones: • Boolean existeUsuarioConNombre(String nombre) Dado un determinado nombre, la operación debe indicar si existe algún usuario en la biblioteca con dicho nombre. • Double calculaPrecioLibros() Esta operación devuelve el precio total correspondiente a la suma de los precios de todos los libros de la biblioteca. • Libro buscaLibroPorAutor(String apellidos) Esta operación devuelve el primer libro de la lista de libros de la biblioteca cuyo autor contenga en sus apellidos la cadena de texto que se introduce como parámetro. Si no se encuentra ningún libro con dicho autor, al probar la operación en el test se deberá devolver el mensaje “La búsqueda realizada no encuentra valor”. • MedioAudiovisual medioAudiovisualMasBarato(TipoAudiovisual ta) Dado un tipo audiovisual determinado, la operación devuelve el medio audiovisual de la biblioteca del tipo indicado que resulte más barato. Si no hay ningún medio del tipo, se debe lanzar una excepción NoSuchElementException. • List<String> seleccionaDNIparaLetraApellido(Character c) Dado un carácter que representa una letra mayúscula, obtener un listado con los DNIs de todos aquellos usuarios cuyo primer apellido empieza por dicha letra. • Boolean todosAudovisualesAnyoTipo(Integer year, TipoAudiovisual tm) Esta operación determina si todos los medios audiovisuales que se adquirieron en un año determinado, corresponden a un mismo tipo de medio audiovisual. EJERCICIOS PARA HACER EN EL AULA 1. Defina la interfaz Biblioteca e implemente la funcionalidad en la clase BibliotecaImpl. Para informar del incumplimiento de la restricción relativa al código de la biblioteca lance excepciones de tipo IllegalArgumentException. 2. Pruebe el tipo en una clase TestBiblioteca, en el paquete fp.tipos.bibliotecas.test. EJERCICIOS PARA HACER EN CASA 3. En una clase de utilidad Bibliotecas implemente métodos estáticos que permitan obtener la siguiente información adicional sobre los usuarios y libros de la biblioteca: a) Dado un conjunto de bibliotecas, se desea conocer si en alguna de ellas existe un usuario con un DNI determinado. Advierta que es necesario aplicar el esquema aplanar puesto que la propiedad DNI pertenece a Usuario, como propiedad heredada del tipo Persona. public static Boolean existeUsuarioConDNI(Set<Biblioteca> sb, String dni) b) La biblioteca necesita conocer los nombres más comunes de sus usuarios para elaborar una pequeña estadística con ellos. Dado un conjunto de usuarios y un determinado nombre, la aplicación debe por tanto devolver cuántos usuarios tienen dicho nombre. B07: Tratamientos Secuenciales 3 public static Integer cuentaUsuariosConNombre(Set<Usuario> su, String nombre) c) La aplicación Biblioteca debe disponer de filtros eficientes. Así, dado un conjunto de usuarios la aplicación debe poder filtrar por un determinado nombre, de forma que únicamente permanezcan en el conjunto los usuarios que NO tienen dicho nombre. public static Set<Usuario> seleccionaUsuarioOtroNombre(Set<Usuario> su, String nombre) d) Dado un conjunto de bibliotecas y un nombre determinado, obtener cuántos usuarios en dichas bibliotecas tienen dicho nombre. Proporcione dos soluciones, una utilizando el método del ejercicio 3. a) (SIN APLANAR) y otra aplicando el esquema aplanar. // Solución 1) public static Integer cuentaUsuariosConNombreEnBibliotecas (Set<Biblioteca>> sb, String nombre) // Solución 2) public static Integer cuentaUsuariosConNombreEnBibliotecas2 (Set<Biblioteca>> sb, String nombre) e) Dada una lista de libros y un determinado número de páginas, obtener el número de libros de la lista que superan el número de páginas establecido como límite en el parámetro de entrada. public static Integer cuentaLibrosConMasDeNumPaginas(List<Libro> ls, Integer numPaginas) f) Dada una lista de libros, el buscador de la aplicación Biblioteca debe localizar el libro de la lista cuyo ISBN coincide con la cadena de texto que se introduzca en el buscador. Si no se encuentra ningún libro con dicho ISBN, el buscador devolverá el mensaje “La búsqueda realizada no encuentra valor”. public static Libro buscaLibroPorISBN(List<Libro> l, String isbn) g) En la configuración por defecto de la aplicación Biblioteca, el número de copias vendidas de un libro se puede estimar en función de su tipo de préstamo y a criterio del administrador de la aplicación. Valores posibles que puede admitir la aplicación son: 1.000 copias si el tipo de préstamo es mensual, 10.000 copias si es semanal y 100.000 copias para los que tienen el tipo de préstamo diario. Dada una lista de libros, implemente un método que permita establecer un valor inicial para el número de copias vendidas de aquellos libros de la lista que tengan un tipo de préstamo determinado. public static void inicializaEstimacionVenta(List<Libro> l, TipoPrestamo tp, Integer estimacionInicial) h) Compruebe en la clase TestBibliotecasB07 la corrección de cada método implementado.