teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

解説修正

2020/03/23 00:55

投稿

jimbe
jimbe

スコア13355

answer CHANGED
@@ -52,9 +52,9 @@
52
52
 
53
53
  ループの中では, プロンプトを表示し, 標準入力からの一行( nextLine() )を Gender 型の from メソッドに渡して, Gender 型に変換(もしくは失敗すれば null) しています.
54
54
 
55
- Gender 型の from メソッドは, 渡された一行をまず Boy に "一致するか?" と聞きます( matches メソッド). 一致します( true ) と言われたら Boy を返します. 一致しなかった( false )ら次に Girl に "一致するか?" と聞き, 一致なら Girl を返します. そしてどちらとも一致しなかったら null を返します.
55
+ Gender 型の from メソッドは, 渡された一行をまず Boy に "一致するか?" と聞きます( matches メソッド). 一致します( true ) と言われたら Boy を返します. 一致しなかった( false )ら次に Girl に "一致するか?" と聞き, 一致なら Girl を返します. そしてどちらとも一致しなかったら null を返します.
56
56
 
57
- Boy や Girl の matches メソッドは, それぞれがパラメータで渡された正規表現( "男|おとこ|[Bb]oy|BOY"/"女|おんな|[Gg]irl|GIRL" ) と一致するかを返しています.
57
+ Boy や Girl の matches メソッドは, それぞれが予めコンストラクタのパラメータで渡された正規表現( "男|おとこ|[Bb]oy|BOY"/"女|おんな|[Gg]irl|GIRL" ) と一致するかを返しています.
58
58
 
59
59
  for 文のループ条件が成立する(ループし続ける)のは, 「"i が(パラメータで受け取った)リトライ回数より小さく" かつ "入力が Gender 型の有効な値( Boy/Girl )に変換出来ていない"」でした.
60
60
  変数 gender は初期値 null で, ループしている間に入力によって Boy か Girl に設定されると ```gender == null``` が成立しなくなり, ループを抜けます. 一方, 何回やっても Boy か Girl にならず i がリトライ回数に達すると, gender = null のままでループを抜けます.

1

解説追加

2020/03/23 00:55

投稿

jimbe
jimbe

スコア13355

answer CHANGED
@@ -36,4 +36,26 @@
36
36
  return gender;
37
37
  }
38
38
  }
39
- ```
39
+ ```
40
+
41
+ 一応解説など.
42
+
43
+ まず, オリジナルでは変数 gender は String 型でしたが, 代わりとなる Gender 型というのを enum で作りました. ( ```enum Gender { ~ }``` の部分)
44
+ String 型の変数であれば ```"男"``` でも ```"Girl"``` でも ```"123"``` でも ```null``` でも入りますが, この Gender 型の変数には ```Gender.Boy```, ```Gender.Girl``` そして ```null``` の3種類しか入りません.
45
+ inputGender メソッドが(中でリトライ等ごにょごにょして)最終結果をこの Gender 型で返すということにすることで, リトライ回数以内に正しく性別が入力されたら Boy か Girl, 入力されなかったら null が返る...という仕様に出来, main メソッドではそれによって null で無ければ性別と"確認できました", null だったら "いい加減に~" と表示しています.
46
+
47
+ さてその inputGender ですが, パラメータとして入力を促すプロンプト文字列("性別を~")とリトライ回数(5)を貰っています. こうすることで, 例えばリトライを 3 回にしよう等の修正の時, 下位のコードを見ること無くこのパラメータを変えるだけで済みます.
48
+
49
+ 変数 gender を用意し, 標準入力から取り込む Scanner も準備します. ( ```try(Scanner scanner = new ~ ) { ~ }``` となっているのは, 一応終了時に scanner を close するためです.)
50
+
51
+ 入力判定・リトライは ```for(int i=0; i<retry && gender==null; i++)``` で行い, 「"i が(パラメータで受け取った)リトライ回数より小さく" かつ "入力が Gender 型の有効な値( Boy/Girl )に変換出来ていない" ならループする」としています.
52
+
53
+ ループの中では, プロンプトを表示し, 標準入力からの一行( nextLine() )を Gender 型の from メソッドに渡して, Gender 型に変換(もしくは失敗すれば null) しています.
54
+
55
+ Gender 型の from メソッドは, 渡された一行をまず Boy に "一致するか?" と聞きます( matches メソッド). 一致します( true ) と言われたら Boy を返します. 一致しなかった( false )ら次に Girl に "一致するか?" と聞き, 一致なら Girl を返します. そしてどちらとも一致しなかったら null を返します.
56
+
57
+ Boy や Girl の matches メソッドは, それぞれがパラメータで渡された正規表現( "男|おとこ|[Bb]oy|BOY"/"女|おんな|[Gg]irl|GIRL" ) と一致するかを返しています.
58
+
59
+ for 文のループ条件が成立する(ループし続ける)のは, 「"i が(パラメータで受け取った)リトライ回数より小さく" かつ "入力が Gender 型の有効な値( Boy/Girl )に変換出来ていない"」でした.
60
+ 変数 gender は初期値 null で, ループしている間に入力によって Boy か Girl に設定されると ```gender == null``` が成立しなくなり, ループを抜けます. 一方, 何回やっても Boy か Girl にならず i がリトライ回数に達すると, gender = null のままでループを抜けます.
61
+ こうして最後の return は, リトライ以内で Boy/Girl となるか, ならずにリトライを終え null のままの gender を返すことで, 最初の inputGender の仕様通りの結果を返すことになります.