Eu estou tentando playaround com Java 8 Fluxo API e queria converter o método a seguir usando Java mapa filtro de 8 fluxo de reduzir.
Eu tenho uma lista de filmes e cada objeto de filme tem uma lista de atores, juntamente com outros campos.
Eu quero encontrar todos os filmes onde o ator com um determinado nome e sobrenome tem trabalhado nele.
O método a seguir é Java 7 com base onde eu loop sobre a lista de filmes e, em seguida, um loop sobre uma lista de atores para esse filme. Se um ator com o primeiro e último nome for encontrado, eu quebrar o loop interno e adicionar esse filme para a lista de filmes que é retornado.
O código comentado funciona e eu posso obter a lista direito de Filmes.
A minha pergunta é como posso voltar a escrever esse código usando Java 8 fluxos. Eu posso ver que é um mapa, filtro, reduzir problema, mas eu não sou capaz de chegar a uma solução clara.
public List<Movie> getMoviesForActor(String firstName, String lastName) {
final List<Movie> allMovies = movieRepository.getAllMovies();
final Predicate<Actor> firstNamePredicate = actor -> actor.getFirstName().equalsIgnoreCase(firstName);
final Predicate<Actor> lastNamePredicate = actor -> actor.getLastName().equalsIgnoreCase(lastName);
final List<Movie> movies = new ArrayList<>();
// for (Movie movie : allMovies) {
// boolean actorFound = false;
// for (Actor actor : movie.getActors()) {
// if(firstName.equalsIgnoreCase(actor.getFirstName()) && lastName.equalsIgnoreCase(actor.getLastName())) {
// actorFound = true;
// break;
// }
// }
// if(actorFound) {
// movies.add(movie);
// }
// }
final List<Actor> actors = allMovies.stream()
.flatMap(
movie -> movie.getActors().stream().filter(firstNamePredicate.and(lastNamePredicate))
).collect(Collectors.toList());
return movies;
}
Se eu transmitir nos filmes e flatmap ela e nela lista de atores transmitir, como posso obter a lista de filmes de novo onde somente este ator com nome e sobrenome existe?
Encontrar o primeiro elemento correspondente ao loop através de uma iterable e quebrar uma vez que é encontrado pode ser facilmente alcançado usando a anyMatch
operação do terminal-circuito curto em Java8. Em seguida, passe o resultado de anyMatch
que o filter
operador para obter todos os filmes que correspondem aos critérios fornecidos.
Eu preferiria sugiro que você usar predicados embutidos em vez de defini-los separadamente a menos que você reutilizá-los em outro lugar. Isto leva a um código mais condensado que é menos extenso. Veja como ele se parece.
movies.stream()
.filter(m -> m.getActors().stream()
.anyMatch(
a -> a.getFirstName().equalsIgnoreCase(firstName)
&& a.getLastName().equalsIgnoreCase(lastName)))
.collect(Collectors.toList());
Por alguma razão, se você realmente precisa usar os predicados pré-definidos como dado na sua declaração de problema que você pode fazê-lo como tal,
movies.stream()
.filter(m -> m.getActors().stream()
.anyMatch(firstNamePredicate.and(lastNamePredicate)))
.collect(Collectors.toList());