FUNDAMENTOS DE PROGRAMACIÓN Curso: 2011/12 PRIMER EXAMEN PARCIAL. 10 de febrero de 2012. SOLUCIONES EJERCICIO 1 - Valoración: 2,5 puntos Se pide el siguiente código: 1. La interfaz Pelicula (0,5 puntos) public interface Pelicula extends Copiable<Pelicula>, Comparable<Pelicula> { String getNombre(); String getNacionalidad(); Genero getGenero(); Double getPresupuesto(); void setPresupuesto(Double x); Integer getAnyo(); } 2. La clase PeliculaImpl que implementa a la interfaz Pelicula. Supóngase ya implementado el tipo enumerado Genero (1,5 puntos) public class PeliculaImpl implements Pelicula { private private private private private String nombre; String nacionalidad; Genero genero; Double presupuesto; Integer anyo; public PeliculaImpl() { this.nombre = ""; this.nacionalidad = ""; this.genero = Genero.INDEFINIDO; this.presupuesto = 0.0; this.anyo = 1895; } public PeliculaImpl(String nombre, String nacionalidad, Genero genero, Double presupuesto, Integer anyo) { if (anyo < 1895) throw new IllegalArgumentException(); if (presupuesto <= 0) throw new PresupuestoNegativoException(); this.nombre = nombre; this.nacionalidad = nacionalidad; this.genero = genero; this.presupuesto = presupuesto; this.anyo = anyo; } public String getNombre() { return nombre; } public String getNacionalidad() { return nacionalidad; } public Genero getGenero() { return genero; } public Double getPresupuesto() { return presupuesto; } public void setPresupuesto(Double x) { if (x.compareTo(0.0) < 0) throw new PresupuestoNegativoException(); presupuesto = x; } public Integer getAnyo() { return anyo; } public String toString() { String s = getNombre() + " (" + getAnyo() + ")"; return s; } public boolean equals(Object o) { boolean res = false; if (o instanceof Pelicula) { Pelicula p = (Pelicula) o; boolean aux1 = this.getNombre().equals(p.getNombre()); boolean aux2 = this.getAnyo().equals(p.getAnyo()); res = aux1 && aux2; } return res; } public int hashCode() { return getNombre().hashCode() + getAnyo().hashCode() * 31; } public Pelicula clone() { Pelicula res = null; try { res = (Pelicula) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return res; } public int compareTo(Pelicula p) { int res = getNombre().compareTo(p.getNombre()); if (res == 0) { res = getAnyo().compareTo(p.getAnyo()); } return res; } } 3. La clase PresupuestoNegativoException (0,5 puntos) public class PresupuestoNegativoException extends RuntimeException { public PresupuestoNegativoException() { super(); } public PresupuestoNegativoException(String s) { super(s); } } FUNDAMENTOS DE PROGRAMACIÓN Curso: 2011/12 PRIMER EXAMEN PARCIAL. 10 de febrero de 2012. SOLUCIONES EJERCICIO 2 - Valoración: 4,5 puntos Se pide la programación de los siguientes métodos de la clase Peliculas: Notas: Algunos métodos se pueden hacer de varias formas, incluyendo la escritura de un método adicional en alguna de las clases PeliculaImpl o PeliculaOnlineImpl. Si en algún momento se debe usar un comparador, deberá implementarse. 1. Dado un conjunto de películas, ¿cuál es la que tiene mayor presupuesto? (0,75 puntos) public static Pelicula masPresupuesto(Set<Pelicula> s) { Pelicula res = null; boolean esPrimero = true; for (Pelicula e : s) { if (esPrimero) { res = e; esPrimero = false; } else { if (res.getPresupuesto().compareTo(e.getPresupuesto()) < 0) { res = e; } } } if (res == null) throw new NoSuchElementException(); return res; } //Segunda opción: hay que programar también el comparador asociado public static Pelicula masPresupuesto(Set<Pelicula> s) { Pelicula res = null; Comparator<Pelicula> cmp = new CompPeliculaPresupuesto(); for (Pelicula e : s) { res = Ordenes.max(res, e, cmp); } if (res == null) throw new NoSuchElementException(); return res; } public class CompPeliculaPresupuesto implements Comparator<Pelicula> { public int compare(Pelicula p1, Pelicula p2) { int res = p1.getPresupuesto().compareTo(p2.getPresupuesto()); // No imprescindible en este problema if (res == 0) { res = p1.compareTo(p2); } return res; } } 2. Dado un conjunto de películas, ¿hay alguna de una determinada nacionalidad? (0,75 puntos) public static Boolean hayNacionalidad(Set<Pelicula> s, String nac) { Boolean res = false; for (Pelicula e : s) { res = res || (e.getNacionalidad().equals(nac)); if (res) { break; } } return res; } 3. Dada una lista de películas y un presupuesto, ¿cuáles son las que tienen un presupuesto superior al dado? El resultado tiene que ser un conjunto ordenado según el año de cada película y de forma que sean recogidas todas las películas de dicho conjunto (1 punto) public static SortedSet<Pelicula> grandesProducciones(List<Pelicula> lista, Double dinero) { Comparator<Pelicula> cmp = new CompPeliculaAnyo(); SortedSet<Pelicula> res = new TreeSet<Pelicula>(cmp); for (Pelicula e : lista) { if (e.getPresupuesto().compareTo(dinero) > 0) { res.add(e); } } return res; } public class CompPeliculaAnyo implements Comparator<Pelicula> { public int compare(Pelicula p1, Pelicula p2) { int res = p1.getAnyo().compareTo(p2.getAnyo()); // Imprescindible el desempate para que no colapsen los objetos if (res == 0) { res = p1.compareTo(p2); } return res; } } 4. Dado un conjunto de películas, obtener un array de String que en cada posición contenga el título de una película seguido por un guión y la nacionalidad de la misma. El array debe estar ordenado alfabéticamente. (0,5 puntos) public static String[] arrayTitulosOrdenado(List<Pelicula> s) { String[] res = new String[s.size()]; for (int i = 0; i < s.size(); i++) { Pelicula p = s.get(i); res[i] = p.getNombre() + "-" + p.getNacionalidad(); } Arrays.sort(res); return res; } 5. Dados tres conjuntos que representan las películas candidatas a los Oscar, los Globos de Oro y los Goya, obtener el conjunto de las películas candidatas a los tres premios simultáneamente. (0,5 puntos) public static Set<Pelicula> candidatas3(Set<Pelicula> s1, Set<Pelicula> s2, Set<Pelicula> s3) { Set<Pelicula> res = new HashSet<Pelicula>(s1); res.retainAll(s2); res.retainAll(s3); return res; } 6. Dada una lista de películas online, obtener el nombre de la película que tiene un mayor número de puntuaciones con valor igual a 10. (1 punto) public static String peliculaConMas10(List<PeliculaOnline> peliculas) { String res = ""; PeliculaOnline aux = null; boolean esPrimero = true; for (PeliculaOnline e : peliculas) { if (esPrimero) { FUNDAMENTOS DE PROGRAMACIÓN Curso: 2011/12 PRIMER EXAMEN PARCIAL. 10 de febrero de 2012. SOLUCIONES aux = e; esPrimero = false; } else { Integer numActual = numPuntuacionesSupDiez(e); Integer numCandidato = numPuntuacionesSupDiez(aux); if (numCandidato.compareTo(numActual) < 0) { aux = e; } } } res = aux.getNombre(); return res; } //Este método se puede poner también como un método adicional del tipo private static Integer numPuntuacionesSupDiez(PeliculaOnline peli) { Integer res = 0; for (Integer e : peli.getPuntaciones()) { if (e.compareTo(10) >= 0) { res++; } } return res; } EJERCICIO 3 - Valoración: 2 puntos Escriba el código de la clase PeliculaOnlineImpl que implementa a la interfaz PeliculaOnline, reutilizando la clase PeliculaImpl por herencia. public class PeliculaOnlineImpl extends PeliculaImpl implements PeliculaOnline { private String linkYotube; private List<Integer> lista; public PeliculaOnlineImpl(String nombre, String nacionalidad, Genero genero, Double presupuesto, Integer anyo, String linkYotube) { super(nombre, nacionalidad, genero, presupuesto, anyo); this.linkYotube = linkYotube; lista = new ArrayList<Integer>(); } public String getLinkYotube() { return this.linkYotube; } public void setLinkYotube(String x) { this.linkYotube = x; } public List<Integer> getPuntaciones() { return this.lista; } public Double getPuntuacionMedia() { Double res = 0.0; for (Integer e : this.getPuntaciones()) { res = res + e; } return res / (double) this.getPuntaciones().size(); } public void anyadirPuntacion(Integer x) { if (0 >= x || 10 >= x) throw new IllegalArgumentException("Puntuación no válida"); this.lista.add(x); } } EJERCICIO 4 - Valoración: 1 punto Se pide la creación de una clase TestPelicula que pruebe el tipo Pelicula de forma intuitiva: public class TestPelicula extends Test { public static void main(String[] args) { … donde: 1. Se cree un objeto del tipo Pelicula con unos valores cualesquiera y se muestre por pantalla. (0,25 puntos) 2. Se cree un segundo objeto del tipo Pelicula y se compruebe si es igual que el anterior. (0,25 puntos) 3. Se obtenga un objeto idéntico al primero y se compruebe que es tanto igual como idéntico al primero. (0,25 puntos) 4. Se modifique el presupuesto del primer objeto con un valor negativo y se gestione el lanzamiento de la excepción correspondiente mediante un mensaje por pantalla. (0,25 puntos) public class TestPelicula extends Test { public static void main(String[] args) { Pelicula p1 = new PeliculaImpl("El acorazado Potemkin", "Rusa", Genero.DRAMA, 10000.0, 1925); mostrar("p1: " + p1); Pelicula p2 = new PeliculaImpl("Tiempos modernos", "EEUU", Genero.COMEDIA, 1500000.00, 1936); mostrar("p2: " + p2); boolean sonIguales = p1.equals(p2); mostrar("¿p1 y p2 son iguales? " + sonIguales); Pelicula p3 = p1; mostrar("p3: " + p3); boolean sonIgualesEIdenticos = (p1.equals(p3) && p1 == p3); mostrar("¿p1 y p3 son iguales e idénticos? " + sonIgualesEIdenticos); try { p1.setPresupuesto(-1000.0); } catch (PresupuestoNegativoException e) { mostrar("No se permiten películas con presupuesto negativo."); } } }