Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
10 kB
1
Indexable
Never
package fp.shows;

import java.time.LocalDate;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import fp.common.Puntuacion;
import fp.utiles.Checkers;







public class Cinematografica {
	
	private LocalDate fechaEstreno;
	private String nombre;
	private Integer usuarios;
	private Boolean compartida;
	private List<Serie> series;
	
	
	public Cinematografica(LocalDate fechaEstreno, String nombre,Integer usuarios,Boolean compartida, List<Serie> series) {
		super();
		this.fechaEstreno = fechaEstreno;
		this.nombre = nombre;
		this.usuarios=usuarios;
		this.compartida=compartida;
		this.series = new ArrayList<>(series);
	}


	public Cinematografica( String nombre,Integer usuarios,Boolean compartida) {
		super();
		
		Checkers.check("El nombre de la serie no puede estar vacío", !nombre.isEmpty());

		
		this.fechaEstreno = LocalDate.now();
		this.nombre = nombre;
		this.usuarios=usuarios;
		this.compartida=compartida;
		this.series = new ArrayList<>();
	}
	
	public Cinematografica( LocalDate fechaEstreno, String nombre,Integer usuarios,Boolean compartida, Stream<Serie> series) {
		super();
		
		Checkers.check("El nombre de la serie no puede estar vacío", !nombre.isEmpty());

		
		this.fechaEstreno = LocalDate.now();
		this.nombre = nombre;
		this.usuarios=usuarios;
		this.compartida=compartida;
		this.series = series.collect(Collectors.toList());
	}


	public Boolean getCompartida() {
		return compartida;
	}


	public void setCompartida(Boolean compartida) {
		this.compartida = compartida;
	}


	public LocalDate getFechaEstreno() {
		return fechaEstreno;
	}


	public String getNombre() {
		return nombre;
	}




	public Integer getUsuarios() {
		return usuarios;
	}


	public List<Serie> getSeries() {
		return new ArrayList<>(series);
	}





	@Override
	public String toString() {
		return "Cinematografica [fechaEstreno=" + fechaEstreno + ", nombre=" + nombre + ", usuarios=" + usuarios
				+ ", compartida=" + compartida + ", series=" + series + "]";
	}


	@Override
	public int hashCode() {
		return Objects.hash(fechaEstreno, nombre);
	}


	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Cinematografica other = (Cinematografica) obj;
		return Objects.equals(fechaEstreno, other.fechaEstreno) && Objects.equals(nombre, other.nombre);
	}

	
	//Otras operaciones
	
	public Integer getNumeroSeries() {
		return series.size();
	}
	
	
	public void añadeSerie(Serie s) {
		if (!series.contains(s)) {
			series.add(s);			
		}
	}
	
	public void añadeSeries(Collection<Serie> c) {
		for (Serie r: c) {
			añadeSerie(r);
		}
		
	}
	
	public void eliminaSerie(Serie s) {
		series.remove(s);
	}
	
	// 1.Si hay series estrenada en ese año vuelve true si no devuelve false. (Tratamiento: existe)
	public Boolean existeSerieEstrenadaEnTalAño(Integer año ) {
		Boolean existeSerie = false;

		for (Serie s: series) {
		   if (s.getFechaEstreno().getYear()==año) {
			   existeSerie = true;
		      break;
		   }
		} 

		return existeSerie;
	}
	
	// 2. Media  calificacion de las series por el numero de temporadas. (Tratamiento: media)
	public Double getMediaCalificacionSeriePorTemporada( Integer temporadas) {
		Double sumaCalificacion = 0.;
		Integer numeroSeries = 0;
		
		for (Serie s: series) {
			if (s.getTemporadas().equals(temporadas) ) {
				sumaCalificacion += s.getCalificacion();
				numeroSeries++;
			}
		}
		
		Double media = null;
		if (numeroSeries > 0) {
		   media = sumaCalificacion / numeroSeries;
		}
		
		return media;
	}
	
    // 3. Series con directores.
	public List<String> getSeriesConDirectores(Set<String> directores) {
		List<String> seriesConDirectores = new ArrayList<>();

		for (Serie s: series) {
		   List<String> directoresComunes = new ArrayList<>(s.getDirectores());
		   directoresComunes.retainAll(directores);
		   if (!directoresComunes.isEmpty()) {
			   seriesConDirectores.add(s.getNombre()); 
		   }
		}

		return seriesConDirectores;
	
	
	}
	
	// 4. (Tratamiento: Map con valores de tipo colección)
	public Map<Genero, List<Serie>> getSeriesPorGenero() {
		Map<Genero, List<Serie>> res = new HashMap<>();
		
		for (Serie s: series) {
			Genero ge = s.getGenero();
			if (res.containsKey(ge)) {
				res.get(ge).add(s);
			} else {
				List<Serie> lista = new ArrayList<>();
				lista.add(s);
				res.put(ge, lista);
			}
		}
		
		return res;		
}
	
	// 5. (Tratamiento: Map contador)
	public Map<String, Integer> getNumeroSeriesConPais() { 
		Map<String, Integer> res = new HashMap<>();
		
		for (Serie s: series) {
			
				List<String> paises = s.getPaises();
				for (String pais:paises) {

				if (res.containsKey(pais)) {
					res.put(pais, res.get(pais) + 1);
				} else {
					res.put(pais,1);
				}				
			}
		}
		
		
		return res;
	}
	
	
	//// 6.Si hay series estrenada en ese año vuelve true si no devuelve false. (Tratamiento: existe) con stream.
	public Boolean existeSerieEstrenadaEnTalAño2(Integer año) {
	    return series.stream()
	            .anyMatch(s -> s.getFechaEstreno().getYear() == año);
	}
	
	// 7. Media  calificacion de las series por el numero de temporadas. (Tratamiento: media) con stream
	public Double getMediaCalificacionSeriePorTemporada2(Integer temporadas) {
	    return series.stream()
	            .filter(s -> s.getTemporadas().equals(temporadas))
	            .mapToDouble(Serie::getCalificacion)
	            .average()
	            .orElse(Double.NaN);
	}
	
	
    // 8. Series con directores.

	public List<String> getSeriesConDirectores2(Set<String> directores) {
	    return series.stream()
	            .filter(s -> s.getDirectores().stream().anyMatch(directores::contains))
	            .map(Serie::getNombre)
	            .collect(Collectors.toList());
	}
	
	
	//9.La serie con la mayor calificación entre aquellas que han sido estrenadas después del año 2010. (Maximo)
	public Serie getSerieMaximaCalificacionEstrenadaDespuesDe2010() {
	    return series.stream()
	            .filter(s -> s.getFechaEstreno().getYear() > 2010)
	            .max(Comparator.comparing(Serie::getCalificacion))
	            .get();
	}
	
	//10.Las 5 series más recientes que hayan sido estrenadas después del año 2000
	public List<Serie> getSeriesRecientesDespuesDe2000(int n) {
	    return series.stream()
	            .filter(s -> s.getFechaEstreno().getYear() > 2000)
	            .sorted(Comparator.comparing(Serie::getFechaEstreno).reversed())
	            .limit(n)
	            .collect(Collectors.toList());
	}
	//11.Metodo 5 con stream.
	public Map<String, Long> getNumeroSeriesConPais2() { 
	    return series.stream()
	            .flatMap(s -> s.getPaises().stream())
	            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
	}
	
	//12.Un método en cuya implementación se use, o bien el Collector collectingAndThen, o bien el Collector mapping.
	public List<String> getDirectores() {
	    return series.stream()
	        .flatMap(s -> s.getDirectores().stream())
	        .distinct()
	        .sorted()
	        .collect(Collectors.mapping(String::toUpperCase, Collectors.toList()));
	}
	//13.Un método que devuelva un Map en el que las claves sean un atributo o una función sobre un atributo, 
	//y los valores son máximos/mínimos de los elementos que tienen ese valor.
    public Map<String, Double> getMaxCalificacionByNombre() {
        return series.stream()
                .collect(Collectors.groupingBy(Serie::getNombre, Collectors.mapping(Serie::getCalificacion, Collectors.maxBy(Comparator.naturalOrder()))))
                .entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().orElse(Double.NaN)));
    }
    
    //14.Devuelve un map ordenado por la cantidad de temporadas de las series.
    public SortedMap<Integer, List<Serie>> getNMejoresPeoresPorTemporadas(int n) {
        Comparator<Serie> byTemporadas = Comparator.comparing(Serie::getTemporadas);
        SortedMap<Integer, List<Serie>> mejoresPeoresPorTemporadas = series.stream()
                .collect(Collectors.groupingBy(Serie::getTemporadas, Collectors.toList()))
                .entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().stream()
                        .sorted(byTemporadas)
                        .limit(n)
                        .collect(Collectors.toList()), (a, b) -> a, TreeMap::new));
        
        return mejoresPeoresPorTemporadas;
    }
    
    

//15.devuelve un Optional que contiene el nombre de la serie con el valor extremo (mayor o menor) 
//en función de la cantidad de temporadas, dependiendo del valor del parámetro mayor
    public Optional<String> obtenerNombreSerieExtremaPorTemporadas(List<Serie> series, boolean mayor) {
        Comparator<Serie> comparator = Comparator.comparing(Serie::getTemporadas);
        if (!mayor) {
            comparator = comparator.reversed();
        }
        
        return series.stream()
                .max(comparator)
                .map(Serie::getNombre);
    }
}