我的应用程序中有一个匹配表,其中包含计划的匹配项的详细信息
我有user
表&一个user_match
表,它是一个桥接表。
user_match
表格指定了哪个用户遵循哪个匹配&支持哪个团队。
现在,在我的控制器方法中,我将返回今天的预定比赛&如果loggedIn用户遵循今天的预定比赛,也会同时检查。
问题是我必须在进程Complexity O(n ^ 2)中运行两个嵌套for循环。首先,我迭代当天的比赛&然后,对于每一天的比赛,我迭代用户跟随的所有比赛&检查当前匹配是否存在。我希望如果我能摆脱嵌套的for循环,是否有更好的方法来解决这个问题。
@RequestMapping(value="/getTodaysMatches", method=RequestMethod.GET, consumes = "application/json", produces = "application/json")
public @ResponseBody List<Match> getMatchesForCurrentDate(){
logger.debug("inside /getTodaysMatches CricketController method");
DateTime currentServerTimeStamp = CricketUtil.getServerDateTime();
List<Match> currentDayMatchList = this.cricketService.fetchMatchesForInputDate(currentServerTimeStamp);
CustomUserDetail myUserDetails = currentUserAccessor.getCurrentLoggedInUser();
User loggedInUser = myUserDetails.getUser();
List<UserMatchInfo> userMatchInfoList = this.cricketService.getUserMatchInfoByUserId(loggedInUser.getUserId());
/*check if the logged in user already follows matches scheduled for today*/
for(Match todaysMatch : currentDayMatchList){
for(UserMatchInfo tmpUserMatchInfo : userMatchInfoList){
String teamFollowedByUser = tmpUserMatchInfo.getSupportingTeam();
Match matchWhichUserFollows = tmpUserMatchInfo.getMatch();
if((matchWhichUserFollows.getMatchId().intValue()) == (todaysMatch.getMatchId().intValue())){
todaysMatch.setLoggedInUserFollowsThisMatch(true);
}
if((todaysMatch.getTeamOne().equals(teamFollowedByUser))){
todaysMatch.setLoggedInUserSupportsTeamOne(true);
}
if((todaysMatch.getTeamTwo().equals(teamFollowedByUser))){
todaysMatch.setLoggedInUserSupportsTeamTwo(true);
}
}
}
return currentDayMatchList;
}
答案 0 :(得分:3)
你提供的列表有些笨拙,因为你搜索了Map的ID,它是Object的子节点,因此它看起来像是一个O(n ^ 2)嵌套for循环,当它可以是优化为O(n)。
相反,将ID转换为HashMap,按ID分配给O(n)。
HashMap<Integer, Match> matchMap = new HashMap<>();
for(Match m : currentDayMatchList) {
int id = m.getMatchId().intValue()
matchMap.put(id, m);
}
这为我们提供了一个由索引映射的HashMap,以及一个带有ID的键集。现在我们不必一遍又一遍地重复比赛。相反,我们可以做一个O(1)get。
for(UserMatchInfo tmpUserMatchInfo : userMatchInfoList){
String teamFollowedByUser = tmpUserMatchInfo.getSupportingTeam();
Match matchWhichUserFollows = tmpUserMatchInfo.getMatch();
if(matchMap.get(matchWhichUserFollows.getMatchId().intValue()) {
//... etc.
}
}
正如您所看到的,for循环已被拆分,因此,不是每次匹配都要执行UserMatch信息,而是先执行UserMatch信息,然后从Map执行O(1),这样性能是O(2n)= O(n)。