【问题标题】:Can I make a method do return for the caller method?我可以让一个方法返回调用者方法吗?
【发布时间】:2017-02-15 18:35:18
【问题描述】:

我想干掉这段代码:

YourConsultant.GameState gameState() {

    for (int i = 0; i < 3; i++) {
        // an 'xxx' column returns 'x', an 'ooo' returns 'o', a mixed row returns '0'
        char c = areTheSame(board[i][0], board[i][1], board[i][2]);
        if (c == 'x') {return YourConsultant.GameState.WON_BY_X;}
        else if (c == 'o') {return YourConsultant.GameState.WON_BY_O;}
    }

    for (int i = 0; i < 3; i++) {
        char c = areTheSame(board[0][i], board[1][i], board[2][i]);
        if (c == 'x') {return YourConsultant.GameState.WON_BY_X;}
        else if (c == 'o') {return YourConsultant.GameState.WON_BY_O;}
    }

    {
        char c = areTheSame(board[0][0], board[1][1], board[2][2]);
        if (c == 'x') {return YourConsultant.GameState.WON_BY_X;}
        else if (c == 'o') {return YourConsultant.GameState.WON_BY_O;}
    }

    {
        char c = areTheSame(board[0][2], board[1][1], board[2][0]);
        if (c == 'x') {return YourConsultant.GameState.WON_BY_X;}
        else if (c == 'o') {return YourConsultant.GameState.WON_BY_O;}
    }

    ...
}

为此,我想编写一个简短的方法来执行此操作:

        if (c == 'x') {return YourConsultant.GameState.WON_BY_X;}
        else if (c == 'o') {return YourConsultant.GameState.WON_BY_O;}

但这会使新方法返回。我想我不能做类似super.return 的事情?我可以再次检查返回值,但它不会使我的代码干燥。你有什么建议? (对不起,如果之前有人问过,我发现这个很难搜索)

更新:我不能简单地传递值,因为如果 areTheSame == 0 那么我不应该返回(还)。

更新 2:我修改了代码,将每两行替换为:

        if (c == 'x' || c == 'o')  return declareWinner(c);

它工作正常,并且做同样的事情。仍然有一些重复,但更好的 IMO。

【问题讨论】:

  • 您可以返回您的新方法 - return myMethod()
  • 哇,谢谢!没想到。
  • 请查看更新。

标签: java return


【解决方案1】:

你不能做超级返回,但是你可以先收集所有的字符,然后返回第一个命中,否则返回null。并且没有任何新方法:

private YourConsultant.GameState gameState() {
    List<Character> chars = new ArrayList<>();
    for (int i = 0; i < 3; i++) {
        chars.add(areTheSame(board[i][0], board[i][1], board[i][2]));
    }

    for (int i = 0; i < 3; i++) {
        chars.add(areTheSame(board[0][i], board[1][i], board[2][i]));
    }

    chars.add(areTheSame(board[0][0], board[1][1], board[2][2]));
    chars.add(areTheSame(board[0][2], board[1][1], board[2][0]));

    return chars.stream()
            .filter(c -> c == 'x' || c == 'o')
            .map(c -> c == 'x' ? YourConsultant.GameState.WON_BY_X : YourConsultant.GameState.WON_BY_O)
            .findFirst()
            .orElse(null); // or whatever "non winning" value you want
}

检查所有井字棋的“性能”影响,而不是停留在第一个可返回状态,将以微秒为单位进行测量。

【讨论】:

  • 我需要迭代所有棋盘位置,但如果速度那么快,那就没问题了。现在的主要障碍是如果所有 3 个都是空的,则 areTheSame 返回 'e'。我不确定要更改被调用的方法或调用。我认为最好更改后者,因为 areTheSame 的名称暗示了这一点。我实现了它,请参阅更新 2。我很乐意尝试您的代码,但我无法重写它,因为我不熟悉 lambdas。
  • @user1257384 无需更改任何内容。此代码返回获胜者,如果当前没有获胜者,则返回 null。返回 '​​e' 不会影响此代码,因为从 areTheSame 返回的 x 和 o 以外的所有字符都将被忽略(由于过滤器)。顺便说一句,我会将棋盘存储在一个一维数组 int[9] 中,并拥有另一个数组 int[8][3] 的获胜位置索引,那么您的方法将是 1 行。
【解决方案2】:

不,方法不能为其调用者执行返回,但调用者可以直接返回被调用方法返回的值。但是,这似乎不符合您的目的,因为您只想有条件地返回。

我会用更深层次的改变来解决这个问题。注意你的四个节是多么相似:不仅仅是条件返回有点湿。您要执行的测试很少,无法枚举,因此您可以考虑以下方面的内容:

private final static int[][][] TRIPLES = new int[][][] {
    { {0, 0}, {0, 1}, {0, 2} },
    { {1, 0}, {1, 1}, {1, 2} },
    { {2, 0}, {2, 1}, {2, 2} },
    { {0, 0}, {1, 0}, {2, 0} },
    { {0, 1}, {1, 1}, {2, 1} },
    { {0, 2}, {1, 2}, {2, 2} },
    { {0, 0}, {1, 1}, {2, 2} },
    { {0, 2}, {1, 1}, {2, 0} },
};

YourConsultant.GameState gameState() {

    for (int i = 0; i < TRIPLES.length; i++) {
        char c = areTheSame(
            board[TRIPLES[i][0][0]][TRIPLES[i][0][1]],
            board[TRIPLES[i][1][0]][TRIPLES[i][1][1]],
            board[TRIPLES[i][2][0]][TRIPLES[i][2][1]]
        );
        if (c == 'x') {
            return YourConsultant.GameState.WON_BY_X;
        } else if (c == 'o') {
            return YourConsultant.GameState.WON_BY_O;
        }
    }

    return YourConsultant.GameState.NO_WINNER;
}

【讨论】:

  • 很好的实现!我在 UPDATE 2 之后阅读了它。可能我会做一个类似的。
【解决方案3】:

你只需要一个 findWinner 方法

private YourConsultant.GameState findWinner(YourConsultant.GameState previousWinner, char boardResult) {
  if (previousWinner!=null) {
      return previousWinner;
  }
  YourConsultant.GameState winner=null;
  switch(boardResult) {
     case 'x': 
         winner = YourConsultant.GameState.WON_BY_X; 
         break;
     case 'o':
         winner = YourConsultant.GameState.WON_BY_O;
         break;
     default:
         winner = null;
  }       
  return winner;
}

那么你的棋盘方法...

YourConsultant.GameState currentWinner=null;

for (int i = 0; i < 3; i++) {
    currentWinner = findWinner(currentWinner,areTheSame(board[i][0], board[i][1], board[i][2]));      
}
for (int i = 0; i < 3; i++) {
   currentWinner = findWinner(currentWinner,areTheSame(board[0][i], board[1][i], board[2][i]));
}
...

当然这不是最有效的方法...

【讨论】:

    猜你喜欢
    • 2011-09-27
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 1970-01-01
    • 2019-11-05
    • 1970-01-01
    相关资源
    最近更新 更多