使用Lambda优化流

时间:2019-01-08 13:14:02

标签: java collections java-stream

进一步优化以下代码的最佳方法是什么

 public List<GroupDTOv2> getAllGroups(String xTenantId, CourseType courseType, String courseId, ContextType contextType, String contextId) throws AuthenticationException {

    final List<GroupV2> groups = groupV2Repository.findByTenantIdAndCourseTypeAndCourseIdAndContextTypeAndContextId(xTenantId, courseType, courseId, contextType, contextId);
    final RosterDTOv2 roster = rosterServiceFacade.getRoster(xTenantId, courseType, courseId, contextType, contextId);

    final ArrayList<GroupDTOv2> groupDtoList=new ArrayList<>();

    groups.stream().forEach(group -> {
        final GroupDTOv2 groupDTO=new GroupDTOv2();
        BeanUtils.copyProperties(group,groupDTO);
        roster.getUsers().forEach(userDTOv2 -> {

            if(userDTOv2.getUserId().equalsIgnoreCase(group.getTeamLeadId())){
                groupDTO.setTeamLead(userDTOv2);
            }

            if(group.getTeamMemberIds().contains(userDTOv2.getUserId())){
                groupDTO.getTeamMembers().add(userDTOv2);
            }

        });
        groupDtoList.add(groupDTO);

    });

    return groupDtoList;
}

如果我们使用流两次来设置团队负责人和团队成员,我认为代价会很高,在那种情况下,最合适的方法是

1 个答案:

答案 0 :(得分:3)

您似乎具有二次复杂度 1),用于查找匹配的领导者和团队成员。考虑将它们放入Map中,将用户ID映射到实际用户:

Map<String, UserDTOv2> userMap = roster.getUsers().stream()
        .collect(Collectors.toMap(user -> user.getUserId().toLowerCase(), 
                                  user -> user));

然后,您不需要内部循环,而只需查找领导者和成员。另外,您可以只使用forEachgroupDtoList.add来代替mapcollect

List<GroupDTOv2> groupDtoList = groups.stream().map(group -> {
        GroupDTOv2 groupDTO = new GroupDTOv2();
        BeanUtils.copyProperties(group, groupDTO);
        groupDTO.setTeamLead(userMap.get(group.getTeamLeadId().toLowerCase()));
        group.getTeamMemberIds().forEach(id -> {
            groupDTO.getTeamMembers().add(userMap.get(id.toLowerCase()));
        });
        return groupDTO;
    }).collect(Collectors.toList());

但是请注意,其行为与代码中的行为并不完全相同。假设(a)没有两个用户具有相同的ID,并且(b)名册实际上将包含该组组长及其每个成员的匹配用户。您的ID允许重复的ID或没有匹配的用户,并且如果找不到匹配的用户,则只会选择最后一个匹配的领导者或忽略成员。

1)并不是二次方,而是O(n * m),其中n是组数,m是用户数。