英文:
Is this use of Optional bad practice here?
问题
我想检查一下我在这里使用 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();
}
}
我的目标是避免创建另一个 'UNKOWN' 枚举实例。
我读到过使用 **Optional.isPresent** 和 **Optional.get** 是不良实践。但是我找不到其他方法来替代使用像 Optional.ifPresent 或者 Optional.map 这样的函数,因为我必须在结果无效时循环。
谢谢。
英文:
I wanted to check if my use of Optional here is against the good practices.
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();
}
}
My goal was to avoid creating another Enum 'UNKOWN' instance.
I read that using Optional.isPresent and Optional.get is bad practice. But I can't find any way around using other functions like Optional.ifPresent or Optinal.map as I have to loop while if result isn't valid yet.
Thank you.
答案1
得分: 1
以下是翻译好的内容:
在您的fromMnemonic
版本中,对于每次调用,您会遍历所有枚举值并检查匹配的常量。相反地,您可以在枚举类型中声明一个静态的Map<Character, Move>
,从助记符到枚举常量,并在类初始化时立即初始化它。然后,您可以在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<Move>
用作fromMnemonic
方法的返回类型,那么方法的主体应该如下所示。
public static Optional<Move> fromMnemonic(char playerInput) {
return Optional.ofNullable(mnemonicToMoveMap.get(playerInput));
}
这样可以保持您的客户端不受影响。
英文:
In your version of fromMnemonic
for each invocation you iterate over the all enum values and check for a matching constant. Conversely, you can declare a static Map<Character, Move>
from mnemonic to enum constant in your enum type and initialize it eagerly at class initialization. Then you can use it inside the fromMnemonic
method like this.
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);
}
And here's how your client looks.
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;
}
If you really need to use Optional<Move>
as the return type of your fromMnemonic
method, then the body of the method should be like this.
public static Optional<Move> fromMnemonic(char playerInput) {
return Optional.ofNullable(mnemonicToMoveMap.get(playerInput));
}
And this leaves your client intact.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论