查找具有名字和姓氏的演员使用Java 8 Streams,map,filter,reduce的电影

Kas*_*hif 6 java reduce dictionary java-8 java-stream

我正在尝试使用Java 8 Stream API进行游戏,并希望使用Java 8流过滤器映射reduce转换以下方法.

我有一个电影列表,每个电影对象都有一个演员列表和其他字段.

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

下面的方法是基于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;
}
Run Code Online (Sandbox Code Playgroud)

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

Rav*_*ala 2

anyMatch使用Java8 中的短路终端操作可以轻松实现在循环迭代时查找第一个匹配元素并在找到后中断。然后将结果传递anyMatchfilter运算符以获得所有符合给定条件的电影。

我宁愿建议您使用内联谓词而不是单独定义它们,除非您在其他地方重用它们。这会导致代码更加简洁,不那么冗长。它看起来是这样的。

movies.stream()
    .filter(m -> m.getActors().stream()
        .anyMatch(
            a -> a.getFirstName().equalsIgnoreCase(firstName) 
                && a.getLastName().equalsIgnoreCase(lastName)))
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

出于某种原因,如果您确实需要使用问题陈述中给出的预定义谓词,您可以这样做,

movies.stream()
    .filter(m -> m.getActors().stream()
        .anyMatch(firstNamePredicate.and(lastNamePredicate)))
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)