【问题标题】:Is this use of Optional bad practice here?这是在这里使用可选的坏习惯吗?
【发布时间】:2020-04-06 05:00:22
【问题描述】:

我想检查一下我在此处使用 Optional 是否违反了良好做法。

public Move getChoice() {

    Optional<Move> move = Optional.empty();
    while (!move.isPresent()) {
        System.out.println("Enter move code : R => Rock, P => Paper, S => Scissors");
        move = Move.fromMnemonic(consoleReader.readPlayerInput());
    }
    return move.get();
}




public enum Move 
{
    ROCK('R'), PAPER('P'), SCISSORS('S');

    private final char mnemonic;
    public static Move[] values = values();

    Move(char mnemonic) {
        this.mnemonic = mnemonic;
    }

    public static Optional<Move> fromMnemonic(char playerInput) {
      return Arrays.stream(values).filter(v -> v.mnemonic == playerInput).findFirst();
    }
}

我的目标是避免创建另一个 Enum 'UNKOWN' 实例。 我读到使用 Optional.isPresentOptional.get 是不好的做法。但是我找不到使用其他函数(如 Optional.ifPresent 或 Optinal.map)的任何方法,因为如果结果还无效,我必须循环。

谢谢。

【问题讨论】:

  • “我读到使用 Optional.isPresent 和 Optional.get 是不好的做法” ????有参考吗?
  • 恕我直言,这太僵化了。 isPresent()get() 是低级的,通常更好地被其他方法替换;并非总是如此。
  • @OleV.V.你的意思是在这种情况下,那些低级的方法是可以接受的?
  • 我还在努力下定决心。 :-) 意思是你可以,而且不明显是否存在更好的解决方案,具体取决于口味。
  • 我投票结束这个问题,因为它属于Code Review

标签: java oop java-8 null optional


【解决方案1】:

在您的fromMnemonic 版本中,对于每次调用,您都会遍历所有枚举值并检查匹配的常量。相反,你可以在你的枚举类型中声明一个从助记符到枚举常量的静态Map&lt;Character, Move&gt;,并在类初始化时急切地初始化它。然后你可以像这样在fromMnemonic 方法中使用它。

private static final Map<Character, Move> mnemonicToMoveMap = Arrays.stream(values)
    .collect(Collectors.toMap(m -> m.mnemonic, m -> m));

public static Move fromMnemonic(char playerInput) {
    return mnemonicToMoveMap.get(playerInput);
}

这是您的客户的外观。

public Move getChoice() {
    Move move = null;
    while (move == null) {
        System.out.println("Enter move code : R => Rock, P => Paper, S => Scissors");
        move = Move.fromMnemonic(consoleReader.readPlayerInput());
    }
    return move;
}

如果你真的需要使用Optional&lt;Move&gt;作为你的fromMnemonic方法的返回类型,那么方法的主体应该是这样的。

public static Optional<Move> fromMnemonic(char playerInput) {
    return Optional.ofNullable(mnemonicToMoveMap.get(playerInput));
}

这会让您的客户完好无损。

【讨论】:

  • 我们可以添加一个方法来检查地图是否包含字符而不执行 == null,但我会看看是否有人建议我使用 Optionals 以更时尚的方式执行此操作..跨度>
  • 当已知元素数量固定为三个时,讨论时间复杂度是不值得的。
  • @Holger 有道理,我已经相应地更新了答案。谢谢。
猜你喜欢
  • 2023-01-05
  • 2015-09-06
  • 1970-01-01
  • 2016-06-27
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多