JAVA:如何基于属性值合并arrayList中的对象?

时间:2018-07-17 17:24:07

标签: java list spring-boot for-loop spring-data-jpa

我正在使用Spring Boot,Java和MySQL构建(或学习如何)运动REST API。我正在构建一种方法,该方法当前从匹配项集合中获取每个匹配项,并为完整的匹配项列表返回ArrayList的{​​{1}}。

这是方法:

TeamStandings

结果是这样的:

public List<TeamStanding> createStandingsTable(Match[] matches){
        List<TeamStanding> teamStandings = new ArrayList<TeamStanding>();
        for(int i = 0;i < matches.length; i++) {
            TeamStanding firstTeam = new TeamStanding();
            TeamStanding secondTeam = new TeamStanding();

            //set team ids
            firstTeam.setIdTeam(matches[i].getWcmHome());
            secondTeam.setIdTeam(matches[i].getWcmAway());


            //first team stats
            firstTeam.setTeamPlayed((long) 1);
            firstTeam.setTeamGoalsFavor(matches[i].getWcmHomeGoals());
            firstTeam.setTeamGoalsAgainst(matches[i].getWcmAwayGoals());
            firstTeam.setTeamGoalDif(firstTeam.getTeamGoalsFavor() - firstTeam.getTeamGoalsAgainst());

            //second team stats
            secondTeam.setTeamPlayed((long) 1);
            secondTeam.setTeamGoalsFavor(matches[i].getWcmAwayGoals());
            secondTeam.setTeamGoalsAgainst(matches[i].getWcmHomeGoals());
            secondTeam.setTeamGoalDif(secondTeam.getTeamGoalsFavor() - secondTeam.getTeamGoalsAgainst());

            //combined team stats

            if(firstTeam.getTeamGoalsFavor() > secondTeam.getTeamGoalsFavor()) {
                firstTeam.setTeamWins((long) 1);
                firstTeam.setTeamLoses((long) 0);
                firstTeam.setTeamDraws((long) 0);
                firstTeam.setTeamPoints((long) 3);
                secondTeam.setTeamWins((long) 0);
                secondTeam.setTeamLoses((long) 1);
                secondTeam.setTeamDraws((long) 0);
                secondTeam.setTeamPoints((long) 0);
            } else if (firstTeam.getTeamGoalsFavor() == secondTeam.getTeamGoalsFavor()) {
                firstTeam.setTeamWins((long) 0);
                firstTeam.setTeamLoses((long) 0);
                firstTeam.setTeamDraws((long) 1);
                firstTeam.setTeamPoints((long) 1);
                secondTeam.setTeamWins((long) 0);
                secondTeam.setTeamLoses((long) 0);
                secondTeam.setTeamDraws((long) 1);
                secondTeam.setTeamPoints((long) 1);
            } else {
                firstTeam.setTeamWins((long) 0);
                firstTeam.setTeamLoses((long) 1);
                firstTeam.setTeamDraws((long) 0);
                firstTeam.setTeamPoints((long) 0);
                secondTeam.setTeamWins((long) 1);
                secondTeam.setTeamLoses((long) 0);
                secondTeam.setTeamDraws((long) 0);
                secondTeam.setTeamPoints((long) 3);
            }
            teamStandings.add(firstTeam);
            teamStandings.add(secondTeam);
        }
        return teamStandings;
    }

我的问题是如何基于[ { "idTeam": 7, "teamPoints": 3, "teamPlayed": 1, "teamWins": 1, "teamDraws": 0, "teamLoses": 0, "teamGoalsFavor": 4, "teamGoalsAgainst": 1, "teamGoalDif": 3 }, { "idTeam": 13, "teamPoints": 0, "teamPlayed": 1, "teamWins": 0, "teamDraws": 0, "teamLoses": 1, "teamGoalsFavor": 1, "teamGoalsAgainst": 4, "teamGoalDif": -3 }, { "idTeam": 4, "teamPoints": 3, "teamPlayed": 1, "teamWins": 1, "teamDraws": 0, "teamLoses": 0, "teamGoalsFavor": 1, "teamGoalsAgainst": 0, "teamGoalDif": 1 }, { "idTeam": 7, "teamPoints": 0, "teamPlayed": 1, "teamWins": 0, "teamDraws": 0, "teamLoses": 1, "teamGoalsFavor": 0, "teamGoalsAgainst": 1, "teamGoalDif": -1 } ] 合并这些对象?我试图实现的结果是在idTeam保持不变的情况下,将所有其他属性加起来。在给定的示例中,预期的是:

idTeam

也只是一个细节,我首先构建了[ { "idTeam": 7, "teamPoints": 3, "teamPlayed": 2, "teamWins": 1, "teamDraws": 0, "teamLoses": 1, "teamGoalsFavor": 4, "teamGoalsAgainst": 2, "teamGoalDif": 2 }, { "idTeam": 13, "teamPoints": 0, "teamPlayed": 1, "teamWins": 0, "teamDraws": 0, "teamLoses": 1, "teamGoalsFavor": 1, "teamGoalsAgainst": 4, "teamGoalDif": -3 }, { "idTeam": 4, "teamPoints": 3, "teamPlayed": 1, "teamWins": 1, "teamDraws": 0, "teamLoses": 0, "teamGoalsFavor": 1, "teamGoalsAgainst": 0, "teamGoalDif": 1 } ] 的{​​{1}},现在我正在尝试将它们合并,但也许我应该将它们堆叠为Matches数组中的循环。上面的方法相同,但我不确定。

3 个答案:

答案 0 :(得分:2)

遍历TeamStanding的列表,注意团队ID并执行添加。您可能希望使用地图将一对团队ID保存为键,将团队本身保存为值,以便于操作。这是片段(我尚未测试过,因此您可能需要对其进行一些修改)。

List<TeamStanding> list = createStandingsTable(matches);
Map<Integer, TeamStanding> map = new HashMap<>();

for (TeamStanding team: list) {
    int id = team.getIdTeam();
    if (map.containsKey(id)) {
        TeamStanding other = map.get(id);
        other.setTeamPoints(team.getTeamPoints());
        other.setTeamPlayed(team.getTeamPlayed());
        // and so on...
    } else {
        map.put(id, team);
    }
}

List<TeamStanding> merged = new ArrayList<>(map.values());

如果要直接从List<TeamStanding>创建合并的Match[],则必须使用相同的想法,但是,将两个迭代组合在一起可能会有些复杂。然后,我建议您坚持使用这两个单独的迭代。简洁性,可读性和可维护性优于性能-而且,这里的性能并不是真正的问题。

答案 1 :(得分:0)

您可以使用HashMap。使用“ idTeam”作为键,使用对象TeamStanding作为值。现在,您可以在结果列表上进行迭代,如果在地图上找到对象,则只需更新其字段即可;如果找不到,则插入对象。迭代完成后,您可以调用map.values(),它将为您提供对象的集合(TeamStanding),然后您可以使用此集合创建一个新的ArrayList。

代码如下:

public List<TeamStanding> mergeTeamStandingList(List<TeamStanding> teamStandingList) {
    final Map<Integer, TeamStanding> idTeamVsTeamStandingMap = new HashMap<Integer, TeamStanding>();
    teamStandingList.forEach(teamStanding -> {
        if(idTeamVsTeamStandingMap.containsKey(teamStanding.getIdTeam())) {
            TeamStanding teamStanding1 = idTeamVsTeamStandingMap.get(teamStanding.getIdTeam());
            teamStanding1.setTeamDraws(teamStanding1.getTeamDraws() + teamStanding.getTeamDraws());
            //so on
        } else {
            idTeamVsTeamStandingMap.put(teamStanding.getIdTeam(), teamStanding);
        }
    });

    return new ArrayList<>(idTeamVsTeamStandingMap.values());
}

答案 2 :(得分:0)

Teamstanding对象上创建合并方法。

public TeamStanding merge(TeamStanding other) {
     this.teamPoints += other.getTeamPoints();
     this.teamPlayed += other.getTeamPlayed();
     this.teamWins += other.getTeamWins();
     this.teamDraws += other.getTeamDraws();
     this.teamGoalsFavor += other.getTeamGoalsFavor();
     this.teamLoses += other.getTeamLoses();
     this.teamGoalDif += other.getTeamGoalDif();
     return this;
}

然后使用Streams按teamId分组并使用merge方法减少常见项目。

Map<Integer, Optional<TeamStanding>> mapReduced = teamStandings
.stream()
.collect(groupingBy(TeamStanding::getIdTeam, Collectors.reducing(TeamStanding::merge)));