Optimizing Stream with lambda

问题: What would be the best way of optimizing the below code further public List<GroupDTOv2> getAllGroups(String xTenantId, CourseType courseType, String courseId, Cont...

问题:

What would be the best way of optimizing the below code further

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

If we use stream twice to set the team-lead object and the team members i think the cost would be high,In that case what would be the mostappropriate way


回答1:

You seem to have quadratic complexity1) for finding the matching leaders and team members. Consider putting those into a Map, mapping user IDs to actual users:

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

Then, you do not need the inner loops and can instead just look up the leader and members. Also, instead of forEach and then groupDtoList.add, you could just usemap and collect.

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());

Note, however, that the behaviour is not exactly the same as in your code. This assumes that (a) no two users have the same ID, and (b) that the roster will actually contain a matching user for the group's leader and each of its members. Yours would allow for duplicate IDs or no matching users and would just pick the last matching leader or omit members if no matching user can be found.

1) Not really quadratic, but O(n*m), with n being the number of groups and m the number of users.

  • 发表于 2019-01-10 01:03
  • 阅读 ( 205 )
  • 分类:网络文章

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除