首页 > 解决方案 > 查找具有名字和姓氏的演员使用 Java 8 Streams、map、filter、reduce 工作过的电影

问题描述

我正在尝试使用 Java 8 Stream API 并希望使用 Java 8 流过滤器映射减少来转换以下方法。

我有一个电影列表,每个电影对象都有一个演员列表以及其他字段。

我想找到具有特定名字和姓氏的演员在其中工作的所有电影。

下面的方法是基于 Java 7 的,我循环遍历电影列表,然后遍历该电影的演员列表。如果找到具有该名字和姓氏的演员,我会中断内部循环并将该电影添加到返回的电影列表中。

注释代码有效,我可以获得正确的电影列表。

我的问题是如何使用 Java 8 流重写此代码。我可以看到这是一个映射、过滤、减少问题,但我无法提出明确的解决方案。

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

如果我在电影上流式传输并对其进行平面映射,并在其中流式传输演员列表,我如何才能再次获得只有这个姓氏和名字的演员存在的电影列表?

标签: javadictionaryjava-8java-streamreduce

解决方案


由于其他答案已经解决了您可以解决问题的方法java-8,因此您可以使用此解决方案中Collectors.filtering引入的所有新功能java-9。因此,请将其留在这里以供将来参考。

List<Movie> movies = allMovies.stream()
                .collect(Collectors.filtering(
                      m -> m.getActors().stream().anyMatch(firstNamePredicate.and(lastNamePredicate)),
                Collectors.toList()));

推荐阅读