好像你可以注意到我试图让用户进入一个特定的项目(我的代码工作)
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());
但是如果我需要在循环中循环呢?
你可以这样做:
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());
你可以这样做,
List<User> users = allUsers.stream()
.filter(u -> u.getProjects().stream().anyMatch(p -> p.getId().equals(projectId)))
.collect(Collectors.toList());
对于每个用户,您需要有一个filter
predicate
来检查用户是否有一个具有给定projectId
值的项目。如果是这样,我们只是将令人满意的User
对象收集到结果容器中。
如果您需要将User
域对象转换为UserDto
类型,如问题陈述中所述,则需要为此类转换添加额外的map
函数。
List<UserDto> users = allUsers.stream()
.filter(u -> u.getProjects().stream().anyMatch(p -> p.getId().equals(projectId)))
.map(u -> new UserDto(u.getProjects()))
.collect(Collectors.toList());
但是你可能需要根据你的UserDto
类改变它。
您可以使用Java 8的stream()
函数来实现它:
usersInSpecificProject.addAll(allUsers.stream()
.filter(u -> u.getProjects().stream().map(Project::getId)
.anyMatch(projId-> projId.equals(projectId)))
.collect(Collectors.toList()));
这里是关于documentation如何工作的stream()
的链接。