Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find Movies where an actor with first and last name has worked using Java 8 Streams, map, filter, reduce

I am trying to playaround with Java 8 Stream API and wanted to convert the following method using Java 8 stream filter map reduce.

I have a list of Movies and every Movie object has a list of Actors along with other fields.

I want to find all the movies where the actor with a specific first and last name has worked in it.

The method below is Java 7 based where I loop over the list of Movies and then loop over a list of actors for that movie. If an actor with that first and last name is found, I break the inner loop and add that movie to the list of movies which is returned.

The commented code works and I can get the right list of Movies.

My question is how can I re-write this code using Java 8 streams. I can see it is a map, filter, reduce problem but I am not able to come up with a clear solution.

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;
}

If I stream on the movies and flatmap it and in it stream list of actors, how can I get the list of movies again where only this actor with first and last name exists?

like image 711
Kashif Avatar asked Feb 08 '19 05:02

Kashif


People also ask

What is Stream in Java 8 example?

Introduced in Java 8, the Stream API is used to process collections of objects. A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result. A stream is not a data structure instead it takes input from the Collections, Arrays or I/O channels.

Does Java 8 have streams?

Java 8 offers the possibility to create streams out of three primitive types: int, long and double. As Stream<T> is a generic interface, and there is no way to use primitives as a type parameter with generics, three new special interfaces were created: IntStream, LongStream, DoubleStream.

What are the two types of streams offered by Java 8?

What are the two types of Streams offered by java 8? Explanation: Sequential stream and parallel stream are two types of stream provided by java.


1 Answers

Since the other answers already addressed the ways you can solve the problem in java-8, with this solution you can use the all new Collectors.filtering introduced in java-9.So just leaving it here for future reference.

List<Movie> movies = allMovies.stream()
                .collect(Collectors.filtering(
                      m -> m.getActors().stream().anyMatch(firstNamePredicate.and(lastNamePredicate)),
                Collectors.toList()));
like image 196
Fullstack Guy Avatar answered Oct 02 '22 16:10

Fullstack Guy