FUNDAMENTOS DE PROGRAMACIÓN BOLETÍN 9.2: Colecciones II. Multimap, Multiset Curso: 2012/13 Versión: 0.0.1 OBJETIVOS Utilizar los tipos Multimap y Multiset. Combinar distintas estructuras de datos en la resolución de un problema. Repasar los métodos de la clase Multimaps. EJERCICIO PROPUESTO Se pretende repetir el estudio realizado en el boletín anterior utilizando los tipos Multimap y Multiset. Partimos del mismo archivo de datos. Almería;17;18;19;21;24;27;30;31;28;24;20;18 Almería;8;9;10;12;15;18;21;22;20;16;12;9 Córdoba;15;17;21;22;26;32;36;36;32;25;19;15 Córdoba;4;5;6;9;12;16;18;19;16;12;8;5 Granada;13;15;19;20;25;30;34;34;29;23;17;14 Granada;0;2;3;6;9;13;15;15;12;8;4;2 Huelva;16;18;20;21;24;28;32;32;29;25;20;17 Huelva;7;8;9;11;13;17;19;19;18;14;10;8 Jerez;16;18;20;22;25;29;33;33;30;25;20;17 Jerez;5;7;8;9;12;15;18;18;17;13;9;7 Málaga;17;18;19;21;24;27;30;30;28;24;20;17 Málaga;7;8;9;10;13;17;20;21;18;14;11;8 Sevilla;16;18;21;23;26;31;35;35;32;26;20;17 Sevilla;5;7;8;10;13;17;19;20;18;14;9;7 Huelva;39 Sevilla;46 Cádiz;37 Granada;42 Jaén;43 Almería;24 Obsérvese de nuevo que se repiten municipios. En el código que se pide a continuación deben utilizarse los métodos factoría de Guava para crear listas, conjuntos, etc. Para encontrar máximos y mínimos de Colecciones deben usarse los métodos max y min de la clase Collections. Se nos pide escribir el código de la clase ClimaAndaluciaImpl2 (de la que no tenemos que escribir equals, hashCode), que implementa ClimaAndalucia. Los métodos tienen el mismo comportamiento descrito en el boletín anterior. a) Escriba el encabezamiento de la clase, añada un atributo Multimap<String, Integer>, un constructor que lo inicialice a vacío usando la factoría LinkedListMultimap, y el método toString() que devuelva la representación como cadena del Multimap. b) Escriba el método cargaDatos(String nombreFichero) para cargar la información del fichero en el Multimap. Aquí habrá que utilizar los métodos fromFile de Iterables2 y separaElementos de Cadenas. c) Escriba el método Integer getTemperaturaMinima() que nos informa sobre cuál es la temperatura mínima registrada durante el año. Boletín 9.2: Colecciones II. Multimap, Multiset 2 d) Escriba el método String getMunicipioConMayorDiferenciaTemperaturas(). Para ello, siga los mismos pasos que en el boletín anterior: 1) Implemente el método estático diferenciaMaxima2 en la clase Climas del paquete fp.util que reciba una cadena que representa un municipio y el Multimap generado en el apartado b) y devuelva la diferencia entre las temperaturas máxima y mínima de ese municipio. 2) Usando el método desarrollado en el punto anterior implemente un Comparator ComparadorMunicipiosPorTemperatura2 para comparar dos municipios (identificados por sus nombres) por su diferencia de temperaturas. Esta clase debe recibir en el constructor el Multimap cuyos valores fueron cargados en el apartado b). 3) Escriba el método String getMunicipioConMayorDiferenciaTemperaturas() usando el comparador anterior. e) Escriba el método SortedSet<String> getMunicipiosPorDebajo(Integer temp) que devuelve un conjunto ordenado por el orden natural de String de todos aquellos municipios que han tenido temperaturas por debajo del argumento que se le pasa. f) Escriba el método getTemperaturasMunicipios() que a partir de la información contenida en el Multimap devuelve un SortedMap<Integer, Set<String>> que hace corresponder a cada temperatura registrada un conjunto con los municipios en los que se ha registrado esa temperatura; las temperaturas estarán ordenadas en orden ascendente. Para ello utilice el método static <K,V,M extends Multimap<K,V>> M invertFrom(Multimap<? extends V,? extends K> source, M dest) Copies each key-value mapping in source into dest, with its key and value reversed. de la clase de utilidad Multimaps, para convertir el Multimap en un SortedSetMultimap con las claves y los valores invertidos y conviértalo en el tipo pedido utilizando el método correspondiente de la clase de utilidad Multimaps2 cuyo código se da a continuación. package fp.util; import import import import java.util.List; java.util.Map; java.util.Set; java.util.SortedSet; import com.google.common.collect.ListMultimap; import com.google.common.collect.SetMultimap; import com.google.common.collect.SortedSetMultimap; @SuppressWarnings("unchecked") public class Multimaps2 { public static <K, V> Map<K, List<V>> asMap(ListMultimap<K, V> listMM) { Map<K, List<V>> res = (Map<K, List<V>>) (Map<?, ?>) listMM.asMap(); return res; } public static <K, V> Map<K, Set<V>> asMap(SetMultimap<K, V> setMM) { Map<K, Set<V>> res = (Map<K, Set<V>>) (Map<?, ?>) setMM.asMap(); return res; } public static <K, V> Map<K, SortedSet<V>> asMap(SortedSetMultimap<K, V> ssMM) { Map<K, SortedSet<V>> res = (Map<K, SortedSet<V>>) (Map<?, ?>) ssMM.asMap(); return res; } public static <K, V> SortedMap<K, Set<V>> asSortedMap(SortedSetMultimap<K, V> ssMM) { SortedMap<K, Set<V>> res = (SortedMap<K, Set<V>>) (Map<?, ?>) ssMM.asMap(); return res; } } Boletín 9.2: Colecciones II. Multimap, Multiset 3 g) Añada a la interfaz ClimaAndalucia el método SortedMap<Integer, Integer> getFrecuenciasTemperaturas(); que devuelve un Map ordenado que relaciona cada temperatura medida con el número total de veces que aparece en el registro de temperaturas. Impleméntelo en la clase ClimaAndaluciaImpl y en la clase ClimaAndaluciaImpl2. En esta última utilice el tipo Multiset. h) Escriba una clase TestClimaAndalucia2 teniendo en cuenta los casos de prueba definidos en la siguiente tabla: Método this Parámetros Resultado i 1 toString 2 getTemperaturaMinima - - 0 3 getMunicipioConMayorDiferenciaTemperaturas - - Granada 4 getMunicipiosPorDebajo - 5 [Córdoba, Granada] 5 getTemperaturasMunicipios - - Nota ii 6 getFrecuenciasTemperaturas - - Nota iii Nota Tabla 1. Casos de prueba para ClimaAndalucia Añada también en TestClimaAndalucia el test de getFrecuenciasTemperaturas, que debe dar el mismo resultado que en TestClimaAndalucia2. i {Almería=[17, 18, 19, 21, 24, 27, 30, 31, 28, 24, 20, 18, 8, 9, 10, 12, 15, 18, 21, 22, 20, 16, 12, 9, 24], Córdoba=[15, 17, 21, 22, 26, 32, 36, 36, 32, 25, 19, 15, 4, 5, 6, 9, 12, 16, 18, 19, 16, 12, 8, 5], Granada=[13, 15, 19, 20, 25, 30, 34, 34, 29, 23, 17, 14, 0, 2, 3, 6, 9, 13, 15, 15, 12, 8, 4, 2, 42], Huelva=[16, 18, 20, 21, 24, 28, 32, 32, 29, 25, 20, 17, 7, 8, 9, 11, 13, 17, 19, 19, 18, 14, 10, 8, 39], Jerez=[16, 18, 20, 22, 25, 29, 33, 33, 30, 25, 20, 17, 5, 7, 8, 9, 12, 15, 18, 18, 17, 13, 9, 7], Málaga=[17, 18, 19, 21, 24, 27, 30, 30, 28, 24, 20, 17, 7, 8, 9, 10, 13, 17, 20, 21, 18, 14, 11, 8], Sevilla=[16, 18, 21, 23, 26, 31, 35, 35, 32, 26, 20, 17, 5, 7, 8, 10, 13, 17, 19, 20, 18, 14, 9, 7, 46], Cádiz=[37], Jaén=[43]} ii {0=[Granada], 2=[Granada], 3=[Granada], 4=[Córdoba, Granada], 5=[Córdoba, Jerez, Sevilla], 6=[Córdoba, Granada], 7=[Huelva, Jerez, Málaga, Sevilla], 8=[Almería, Córdoba, Granada, Huelva, Jerez, Málaga, Sevilla], 9=[Almería, Córdoba, Granada, Huelva, Jerez, Málaga, Sevilla], 10=[Almería, Huelva, Málaga, Sevilla], 11=[Huelva, Málaga], 12=[Almería, Córdoba, Granada, Jerez], 13=[Granada, Huelva, Jerez, Málaga, Sevilla], 14=[Granada, Huelva, Málaga, Sevilla], 15=[Almería, Córdoba, Granada, Jerez], 16=[Almería, Córdoba, Huelva, Jerez, Sevilla], 17=[Almería, Córdoba, Granada, Huelva, Jerez, Málaga, Sevilla], 18=[Almería, Córdoba, Huelva, Jerez, Málaga, Sevilla], 19=[Almería, Córdoba, Granada, Huelva, Málaga, Sevilla], 20=[Almería, Granada, Huelva, Jerez, Málaga, Sevilla], 21=[Almería, Córdoba, Huelva, Málaga, Sevilla], 22=[Almería, Córdoba, Jerez], 23=[Granada, Sevilla], 24=[Almería, Huelva, Málaga], 25=[Córdoba, Granada, Huelva, Jerez], 26=[Córdoba, Sevilla], 27=[Almería, Málaga], 28=[Almería, Huelva, Málaga], 29=[Granada, Huelva, Jerez], 30=[Almería, Granada, Jerez, Málaga], 31=[Almería, Sevilla], 32=[Córdoba, Huelva, Sevilla], 33=[Jerez], 34=[Granada], 35=[Sevilla], 36=[Córdoba], 37=[Cádiz], 39=[Huelva], 42=[Granada], 43=[Jaén], 46=[Sevilla]} iii {0=1, 2=2, 3=1, 4=2, 5=4, 6=2, 7=6, 8=9, 9=9, 10=4, 11=2, 12=6, 13=6, 14=4, 15=7, 16=6, 17=12, 18=13, 19=8, 20=11, 21=7, 22=3, 23=2, 24=6, 25=5, 26=3, 27=2, 28=3, 29=3, 30=5, 31=2, 32=5, 33=2, 34=2, 35=2, 36=2, 37=1, 39=1, 42=1, 43=1, 46=1}