我想避免以下代码中的其他建议吗?

时间:2019-07-14 09:27:07

标签: if-statement java-8

构建动态足球联赛表格生成器。足球排行榜。每个团队进行多次比赛,每场比赛的结果将构成表格。

有人建议避免使用if-else语句吗?

matches.stream().forEach(match -> {
            // Find the record of home team and away team in the league table
            homeTeamRecord = tableEntries.stream().filter(t -> t.getTeamName().equals(match.getHomeTeam())).findFirst().get();
            awayTeamRecord = tableEntries.stream().filter(t -> t.getTeamName().equals(match.getAwayTeam())).findFirst().get();

            /*If home team score > away team score, then
             * home team + 3 points
             * home team's wins + 1
             * away team's lost + 1 
             */
            if (match.getHomeScore() > match.getAwayScore()) {
                homeTeamRecord.setPoints(homeTeamRecord.getPoints() + 3);
                homeTeamRecord.setWon(homeTeamRecord.getWon()       + 1);
                awayTeamRecord.setLost(awayTeamRecord.getLost()     + 1);               
            /*If home team score < away team score, then
             * away team + 3 points
             * away team's wins + 1
             * home team's lost + 1 
             */
            } else if (match.getHomeScore() < match.getAwayScore()) {
                awayTeamRecord.setPoints(awayTeamRecord.getPoints() + 3);
                awayTeamRecord.setWon(awayTeamRecord.getWon()       + 1);
                homeTeamRecord.setLost(homeTeamRecord.getLost()     + 1);           
            /*If home team score equals to away team score, then
             * home team + 1 point
             * away team + 1 point
             * home team's draws + 1
             * away team's draws + 1 
             */
            } else if (match.getHomeScore() == match.getAwayScore()) {
                homeTeamRecord.setPoints(homeTeamRecord.getPoints() + 1);
                awayTeamRecord.setPoints(awayTeamRecord.getPoints() + 1);
                homeTeamRecord.setDrawn(homeTeamRecord.getDrawn()   + 1);
                awayTeamRecord.setDrawn(awayTeamRecord.getDrawn()   + 1);
            }

            // Calculate 'played', 'goals for', 'goals against', 'goal difference' of home team and away team according to their latest match result
            homeTeamRecord.setPlayed(homeTeamRecord.getPlayed() + 1);
            awayTeamRecord.setPlayed(awayTeamRecord.getPlayed() + 1);
            homeTeamRecord.setGoalsFor(homeTeamRecord.getGoalsFor() + match.getHomeScore());
            awayTeamRecord.setGoalsFor(awayTeamRecord.getGoalsFor() + match.getAwayScore());
            homeTeamRecord.setGoalsAgainst(homeTeamRecord.getGoalsAgainst() + match.getAwayScore());
            awayTeamRecord.setGoalsAgainst(awayTeamRecord.getGoalsAgainst() + match.getHomeScore());
            homeTeamRecord.setGoalDifference(homeTeamRecord.getGoalDifference() + match.getHomeScore() - match.getAwayScore());
            awayTeamRecord.setGoalDifference(awayTeamRecord.getGoalDifference() + match.getAwayScore() - match.getHomeScore());

            // Update the league table with the latest team record
            tableEntries.set(tableEntries.indexOf(homeTeamRecord), homeTeamRecord);
            tableEntries.set(tableEntries.indexOf(awayTeamRecord), awayTeamRecord);
        });

2 个答案:

答案 0 :(得分:1)

长话短说:保留您的条件陈述。
我们通常建议您将它们重构为子类,因为它们代表不同的抽象,但是您不应该使用这种子类。
作为子类的替代方法,在Map<Predicate<Match, BiConsumer<Team,Team>>中定义它们不一定是最好的方法。

这里有3种情况需要检查:

  • 主队获胜
  • 客队获胜
  • 平等

要确定实际案例,您需要比较两个团队的计算结果。
条件语句似乎是执行任务的正确方法。

假设您引入了一种抽象方法,以使用ResultRule方法摆脱诸如boolean applyRule(Match match, Team homeTeamRecord, Team awayTeamRecord)接口之类的链式条件语句,并将每种情况的逻辑作为ResultRule的3个子类进行移动。
例如HomeWinRule看起来像:

public HomeWinRule implements ResultRule{   

   public boolean applyRule(Match match, Team homeTeamRecord, Team awayTeamRecord){
       if (match.getHomeScore() > match.getAwayScore()) {
            homeTeamRecord.setPoints(homeTeamRecord.getPoints() + 3);
            homeTeamRecord.setWon(homeTeamRecord.getWon()       + 1);
            awayTeamRecord.setLost(awayTeamRecord.getLost()     + 1);
            return true;
      }    
      return false;
}

好吗?
引入此类和这些子类并不会带来太大的价值,因为功能上的情况是有限的:胜利/失败/平等。您可能不会添加或删除新案例,案例内部的逻辑非常简单。此外,条件语句不会消失,而是会进入子类,您会注意到,因为这里您不依赖多态,而是依赖一系列规则检查/应用。
当可以经常添加/删除/修改规则时,这种模式很有意义,因此您想将其隔离。

答案 1 :(得分:1)

我同意davidxxx的观点,在这种特殊情况下,if语句比其他任何方法都更好。但是,如果您确实必须执行此操作,或者希望通过练习了解如何执行此操作,则可以尝试以下操作:

 int d = Integer.signum(match.getHomeScore() - match.getAwayScore());

如果主队获胜,这将产生1,如果是平局则为0,如果客队取得胜利则为-1。 (不管实际分数有多大。)

然后考虑一下:

int[] pointTable = { 0, 1, 3 };
int points = pointTable[d + 1];

这将产生013,具体取决于是否有客胜,平局或主场胜利。

(甚至可能有一些从points来计算d的方法,它只涉及数学函数而不涉及表查找,但我怀疑通过查看它会更容易理解。) / p>

因此,一旦有了dpoints,您要做的就是从问题中显示的每个字段中分别加上或减去dpoints 。无需if条语句。

这个想法的实际实现留给读者练习。

(我们在这里为您提供帮助,我们不是在这里为您做功课。)

(另外:“程序代码”一词中的“代码”一词是 不可计数 。没有“代码”之类的东西。)