问题:
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.