首页 > 解决方案 > 将双 foreach 和 if 语句重构为 java 8 解决方案

问题描述

就像您注意到的那样,我尝试让用户参与特定项目(并且我的代码有效)

List<User> allUsers = userRepository.findAll();
List<UserDto> usersInSpecificProject = new ArrayList<>();

for(User user: allUsers){
    Set<Project> allProjects = user.getProjects();
    for(Project project: allProjects){
    if(project.getId().equals(projectId)){
            usersInSpecificProject.add(user);
        }
    }
}

如果我可以轻松地做类似的事情,那么它会是单身的+:

allUsers.stream()
    .filter(u -> u.someCondition)
    .collect(Collectors.toList());

但是如果我需要在一个循环中循环呢?

标签: javalambdajava-8java-stream

解决方案


你可以这样做:

List<User> usersInSpecificProject =
  allUsers.stream()
        .filter(u -> u.getProjects().stream()
                                    .map(Project::getId)
                                    .anyMatch(pid -> pid.equals(projectId)))
        .collect(Collectors.toList());

您的原始版本应在满足break条件后进行改进if(project.getId().equals(projectId))

这就是为什么在第一场比赛中filter使用anyMatch()打破。

对于更优雅的版本,您可以考虑我们的过滤器:

Predicate<User> hasProject = u -> u.getProjects().stream()
                                   .map(Project::getId)
                                   .anyMatch(pid -> pid.equals(projectId));
List<User> result = allUsers.stream().filter(hasProject).collect(toList());

推荐阅读