FUNDAMENTOS DE PROGRAMACIÓN BOLETÍN DE PROBLEMAS 19: FUNCTION Y ORDERING Curso: 2011/12 Versión: 1.0.0 OBJETIVOS Aprender a generalizar determinados esquemas de tratamiento secuencial mediante el encapsulamiento de funciones. Implementar funciones y acciones. Utilizar la clase Ordering. EJERCICIO 1: FUNCIONES 1. En este ejercicio vamos a implementar algunos métodos estáticos que trabajan sobre un array de objetos de tipo Fecha. Observaremos que, en ocasiones, el código que necesitamos para solucionar distintos problemas es muy parecido. Buscaremos entonces algún mecanismo que nos permita solucionar problemas parecidos utilizando siempre el mismo código. a) Defina un método estático getDias en la clase Fechas que reciba un array de Fecha como parámetro y devuelva una lista de Integer con la propiedad día de cada una de las fechas del array. b) Defina un método estático getMeses que reciba un array de Fecha como parámetro y devuelva una lista de Integer con la propiedad mes de cada una de las fechas del array. c) En el método main de la clase TestFechas, cree un array de fechas y muestre por pantalla los días de las fechas del array utilizando el método getDias de la clase Fechas. Muestre también los meses de las fechas utilizando el método getMeses. 2. Si observa el código de los métodos getDias y getMeses observará que son muy parecidos. Para poder generalizar ambos problemas y resolverlos mediante un sólo método, necesitamos encapsular el trozo de código que varía entre ambos métodos. Esto lo haremos utilizando la interfaz Function incluida en la librería Guava. public interface Function<F,T>{ T apply(F o); } Una función dispone de un método apply que permite obtener algún resultado de tipo T a partir de un objeto de tipo F. En el método getDias, para cada fecha del array, obteníamos un Integer (los días). Igualmente, en el método getMeses, para cada fecha del array obteníamos un Integer (los meses). Usando la interfaz Function podemos generalizar ambos problemas e implementarlos mediante un sólo método. a) Defina un método estático getFuncion en la clase Fechas que reciba como parámetro un array de Fecha y una Function<Fecha,Integer> y devuelva una lista de Integer con los resultados de aplicar la función a cada una de las fechas del array. b) En el paquete fecha, defina una clase de nombre FuncionFechaDia que implemente la interfaz Function<Fecha,Integer>. El método apply debe devolver la propiedad día de la fecha recibida como parámetro. c) En el paquete fecha, defina una clase de nombre FuncionFechaMes que implemente la interfaz Function<Fecha,Integer>. El método apply debe devolver la propiedad mes de la fecha recibida como parámetro. Boletín de Problemas 19: Function y Ordering 2 d) En el método main de la clase TestFechas, muestre por pantalla los días y los meses de las fechas del array fechas. Para ello, construya sendos objetos de las clases FuncionFechaDia y FuncionFechaMes e invoque adecuadamente al método getFuncion de la clase Fechas. EJERCICIO 2: MÉTODO arrayTitulosOrdenado Implemente una función que dada una Película devuelva una cadena formada por el título de la película seguido de un guión y la nacionalidad de la misma. Una vez hecho esto: 1. Reimplemente el siguiente método de la clase Peliculas: public static String[] arrayTitulosOrdenado(List<Pelicula> l); haciendo uso de la función anterior. 2. Reimplemente el mismo método haciendo uso del método transform de la clase Iterables de Guava. (NOTA: No borre el método original; incluya en su lugar dos nuevos métodos llamados arrayTitulosOrdenado_Function y arrayTitulosOrdenado_Transform) EJERCICIO 3: ACCIONES 1. En algunas ocasiones, el trozo de código que hay que encapsular para conseguir generalizar problemas parecidos e implementarlos mediante un solo método consiste en una o varias sentencias que no devuelven ningún objeto, sino que modifican dichos objetos. Para generalizar este tipo de problemas, utilizaremos la misma interfaz del ejercicio 1 (Function), haciendo que devuelva un valor de tipo Void. a) Defina un método aplicaAccion en la clase Personas que reciba como parámetros un array de Persona y una Function<Persona,Void> e invoque al método apply de la función sobre cada elemento del array. b) En el paquete persona, defina una clase de nombre AccionPersonaCumpleanyos que implemente la interfaz Function<Persona,Void>. Defina el método apply para que se incremente en uno la edad de la persona recibida como parámetro. c) En el método main de la clase TestPersonas, cree un array de personas y escriba el código necesario para incrementar en un año la edad de todas las personas del array, utilizando el método aplicaAccion de la clase Personas. 2. Ampliemos un poco la funcionalidad del método aplicaAccion: a) Defina un método aplicaAccion en la clase Personas que reciba, además del array de Persona y la Function<Persona,Void>, un Predicate<Persona>, de manera que el método apply será invocado sólo sobre aquellas personas del array que cumplan el predicado. Boletín de Problemas 19: Function y Ordering 3 b) En el paquete persona, defina una clase de nombre PredicadoPersonaMayorDe que implemente la interfaz Predicate<Persona>. Incluya un constructor que reciba un entero y lo almacene en un atributo edad. El método apply devolverá cierto si la persona recibida es mayor que la edad especificada en el atributo edad. c) En el método main de la clase TestPersonas, escriba el código necesario para hacer cumplir años a aquellas personas del array personas que sean mayores de 21 años. EJERCICIO 4: ORDERING En la clase utilidad Canciones escriba cada uno de los siguientes métodos estáticos y pruebe su correcto funcionamiento en la clase TestOrdering. Haga uso en todos los casos de la clase Ordering: 1. Un método que reciba una lista de canciones y devuelva una copia de la lista, ordenada por el año de las canciones. public static List<Cancion> creaCopiaOrdenadaPorAño (List<Cancion> listaCanciones) 2. Un método que reciba una lista de canciones y devuelva una copia de la lista, ordenada por el orden natural de las canciones. public static List<Cancion> creaCopiaOrdenada (List<Cancion> listaCanciones) 3. Dada una lista de canciones y un objeto de tipo Cancion, devuelva la posición de dicha canción según el orden obtenido a partir del criterio de orden natural. public static int busquedaDeCancion(List<Cancion> listaCanciones, Cancion c) 4. Dada una lista de canciones devuelva la canción más antigua. Tenga en cuenta que en la lista pueden aparecer objetos null. public static listaCanciones) Cancion cancionMasAntigua(List<Cancion> EJERCICIO 5: EJERCICIOS DE TEORÍA Realice los ejercicios del boletín de ejercicios de teoría de la unidad didáctica 20, y pruebe el funcionamiento de los distintos métodos en una clase de test.