当前位置: 首页 > 知识库问答 >
问题:

查找使用Java8 Streams,地图,筛选,减少名字和姓氏的演员工作过的电影

汪兴为
2023-03-14

我正在尝试使用Java8流API,并希望使用Java8流过滤器map reduce转换以下方法。

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

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

下面的方法Java7,我循环播放电影列表,然后循环播放该电影的演员列表。如果找到了具有该名字和姓氏的演员,我将打破内部循环,并将该电影添加到返回的电影列表中。

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

我的问题是我怎么能重写这个代码使用Java8流。我可以看到这是一个映射,过滤,减少问题,但我不能想出一个明确的解决方案

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

如果我对电影进行流式处理,并对其进行平面映射,然后在流式处理演员列表时,我如何再次获得只有这个名演员和姓氏演员的电影列表?

共有3个答案

严劲
2023-03-14

用现有代码编写它的更好方法(功能)是:

final Predicate<Movie> movieIncludesActor = movie -> movie.getActors()
        .stream()
        .anyMatch(firstNamePredicate.and(lastNamePredicate)); // check both the condition for all actors
final List<Movie> movies = allMovies.stream()
        .filter(movieIncludesActor) // movie which has such an actor
        .collect(toList());
甘兴学
2023-03-14

使用Java8中的anyMatch短路终端操作,可以很容易地找到第一个匹配元素,同时在iterable上循环并在找到它后断开。然后将anyMatch的结果传递给filter操作符,以获得与给定条件匹配的所有电影。

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

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

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

movies.stream()
    .filter(m -> m.getActors().stream()
        .anyMatch(firstNamePredicate.and(lastNamePredicate)))
    .collect(Collectors.toList());
郝承悦
2023-03-14

由于其他答案已经解决了在java-8中解决问题的方法,因此使用此解决方案,您可以使用全新的收集器。过滤java-9中介绍。所以就把它留在这里,以备将来参考。

List<Movie> movies = allMovies.stream()
                .collect(Collectors.filtering(
                      m -> m.getActors().stream().anyMatch(firstNamePredicate.and(lastNamePredicate)),
                Collectors.toList()));
 类似资料:
  • 我有一张名为“有益”的表。关于它的一些事实: 受益人属于一个组织 一个组织有许多有益的 受益人有名字和姓氏,没有其他身份证明形式 表中的一些示例数据 我想通过名字和姓氏查找来自某个组织的有益信息是否也存在于其他组织中,如果是,我想获取组织ID。 在上面的示例数据中,我想要的是给定组织id,查询应该返回,因为对组织也有好处但不是因为即使它们匹配名字,它们也不匹配姓氏 我提出了以下问题: 它有点工作,

  • 本文向大家介绍使用JavaScript拆分名字和姓氏?,包括了使用JavaScript拆分名字和姓氏?的使用技巧和注意事项,需要的朋友参考一下 假设以下是我们的名称字符串- 使用分割名字和姓氏。以下是代码- 示例 要运行上述程序,您需要使用以下命令- 输出结果 在这里,我的文件名为demo163.js。这将产生以下输出-

  • 我需要帮助来分别获得名字和姓氏。 字段为[全名]:Halsey S Dunn 我可以单独获得名字,但无法单独获得姓氏: 这是我的名字和姓氏代码: 我的结果需要是:

  • 问题内容: 我有一个客户列表,其名称为全名。我想创建一个将全名作为参数并分别返回名字和姓氏的函数。如果不可能,我可以有两个单独的函数,一个返回名字,另一个返回姓氏。全名列表包含最多三个单词的名称。我想要的是: 全名由两个词组成时。第一个应该是名称,第二个应该是姓氏。 当一个全名由三个词组成时。第一个单词和中间单词应为名字,第三个单词应为姓氏。 例子:- 结果:- 我搜索并找到了无法按预期运行的解决

  • 谁能告诉我如何从表单字段中检索firstname和lastname的值。条件是名和姓写在同一文本字段中,并用(空格)分隔。我需要得到它的价值。 普朗克尔

  • 我有两个字段FirstName和LastName存储在MongoDB中。从前端,我接收到一个字符串,包含名字和姓氏,用空格分隔,我需要一个查找查询,搜索名字和姓氏的组合。