Java 在迭代复杂对象时避免嵌套for循环

Java 在迭代复杂对象时避免嵌套for循环,java,performance,Java,Performance,我的应用程序中有一个匹配表,其中包含计划的匹配的详细信息 我有一个user表和一个user\u match表,这是一个桥接表 user\u match下表指定了关于哪个用户遵循哪个匹配并支持哪个团队的信息。 现在,在我的控制器方法中,我返回今天的预定匹配&同时还检查loggedIn用户是否遵循今天的预定匹配 问题是我必须在进程复杂性O(n^2)中运行两个嵌套for循环。首先,我遍历当前匹配项&然后,对于每个当前匹配项,我遍历用户遵循的所有匹配项&检查当前匹配项是否存在。我希望如果我能摆脱嵌套

我的应用程序中有一个匹配表,其中包含计划的匹配的详细信息

我有一个
user
表和一个
user\u match
表,这是一个桥接表

user\u match
下表指定了关于哪个用户遵循哪个匹配并支持哪个团队的信息。

现在,在我的控制器方法中,我返回今天的预定匹配&同时还检查loggedIn用户是否遵循今天的预定匹配

问题是我必须在进程复杂性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;
}
@RequestMapping(value=“/getTodaysMatches”,method=RequestMethod.GET,consumes=“application/json”,products=“application/json”)
public@ResponseBody List getMatchesForCurrentDate(){
debug(“inside/getTodaysMatches-controller方法”);
DateTime currentServerTimeStamp=CricketUtil.getServerDateTime();
List currentDayMatchList=this.cricketService.fetchMatchesForInputDate(currentServerTimeStamp);
CustomUserDetail myUserDetails=currentUserAccessor.getCurrentLoggedInUser();
User loggedInUser=myUserDetails.getUser();
List userMatchInfoList=this.cricketService.getUserMatchInfoByUserId(loggedInUser.getUserId());
/*检查登录的用户是否已遵循今天安排的匹配*/
对于(今天匹配匹配:currentDayMatchList){
对于(UserMatchInfo-tmpUserMatchInfo:userMatchInfoList){
字符串TeamFollowDBYuser=tmpUserMatchInfo.getSupportingTeam();
Match MatchwhichUserFollowing=tmpUserMatchInfo.getMatch();
if((matchwhichUserFollowing.getMatchId().intValue())==(todaysMatch.getMatchId().intValue()){
todaysMatch.setLoggedInUserFollowsThisMatch(true);
}
if((todaysMatch.getTeamOne().equals(teamfollowdbyuser))){
todaysMatch.setLoggedInUserSupportsTeamOne(true);
}
if((todaysMatch.getTeamTwo().equals(teamfollowdbyuser))){
todaysMatch.setloggedinusersupportstreamtwo(true);
}
}
}
返回currentDayMatchList;
}

您提供的列表有些笨拙,因为您是通过ID来搜索映射的,ID是对象的子对象,所以它看起来像一个O(n^2)嵌套的for循环,可以将其优化为O(n)

相反,根据O(n)的ID将列表转换为HashMap


如您所见,for循环已被拆分,因此,您不是为每个匹配都执行UserMatch信息,而是执行一次UserMatch信息,然后从映射中执行一个O(1),因此性能是O(2n)=O(n)。

索引数据(在某些映射中)可能不是O(n^2),也就是O(n*m),这真的不是什么大问题。您是否真的面临性能问题?这听起来更像是过早的优化?然后“忘记”性能。相反,重点是创建可读代码。例如,通过学习“单一责任”和“单一抽象层”原则。这将有助于提高代码的质量。选项1:通过简单地连接已有的两个表,以更高效的方式查询数据库。通过这种方式,您可以利用数据库的索引和性能优化。选项2:不要更改任何内容,因为代码可能不是问题。如果您确实反对嵌套fors,并且不愿意更改DB查询,那么另一种选择是使用Java进行交集。更多的代码,更多的hashmaps,没有嵌套for循环,但最终会得到相同的结果。
HashMap<Integer, Match> matchMap = new HashMap<>();

for(Match m : currentDayMatchList) {
    int id = m.getMatchId().intValue()
    matchMap.put(id, m);
}
for(UserMatchInfo tmpUserMatchInfo : userMatchInfoList){
    String teamFollowedByUser = tmpUserMatchInfo.getSupportingTeam();
    Match matchWhichUserFollows = tmpUserMatchInfo.getMatch();
    if(matchMap.get(matchWhichUserFollows.getMatchId().intValue()) {
        //... etc.

    }
}