連想配列のなかからユーザーに一つ選択してもらうようなユーティリティーを作ります。今までいろいろなユーティリティを作ったので過去記事はこちらから参照してください。今回のメソッドの中でもこれを利用します。
ユースケースを考える
完成した動作を先に考えて設計するのも一つの方法です。まず以下のような動作を想定します。
[アイスクリーム] c:チョコレート o:オレンジシャーベット s:ストロベリー v:バニラ 好きな味を選んでください>
アイスクリームの味を選んでもらいます。連想配列は鍵がアルファベット1文字、値が味の名前になっています。これを
[タイトル] 鍵:値(連想配列のエントリーの数分繰り返し) メッセージ>
のように表示して入力を求めます。
好きな味を選んでください>o 選んだのはオレンジシャーベットですね。
鍵を入力することによって連想配列から適切なエントリーを取得してユーザーに知らせるようにしています。
入力は以前作ったreadStringメソッドを使って文字列を取得します。また入力された文字列が連想配列の鍵の一つであるかはHashMapクラスのcontainsKeyで判定します。
実装する
ではこのメソッドをユーティリティークラスの一つであるTerminalUtilクラスに追加します。
public String readKey(String title, String message, HashMapmap){ out.println("[" + title + "]"); for(String key:map.keySet()){ out.println(key + ":" + map.get(key)); } while(true){ String str = readString(message); if(map.containsKey(str)){ return str; } out.println("選択肢にありません。"); } }
引数にはタイトルとメッセージ、それに選択対象の連想配列を指定します。次に実処理を行うコードを書きます。
TerminalUtil util = new TerminalUtil(); LinkedHashMapmap = new LinkedHashMap(); map.put("c", "チョコレート"); map.put("o", "オレンジシャーベット"); map.put("s", "ストロベリー"); map.put("v", "バニラ"); String key = util.readKey("アイスクリーム", "好きな味を選んでください", map); System.out.println("選んだのは" + map.get(key) + "ですね。");
通常のHashMapでなくそのサブクラスであるLinkedHashMapというクラスを使っているのは次のような理由からです。通常のHashMapはエントリーの順序を保持してくれません。今回チョコレート、オレンジシャーベット、ストロベリー、バニラの順に表示したいとしても通常のHashMapでは順番が入れ替わってしまう可能性があるのです。このため設定した順序を保つように実装されているサブクラスのLinkedHashMapを利用しています。ユーティリティーメソッドは指定のクラスかそのサブクラスであれば引数として受け入れるのでサブクラスの利用は問題ありません。
では実行結果になります。
[アイスクリーム] c:チョコレート o:オレンジシャーベット s:ストロベリー v:バニラ 好きな味を選んでください> なにも入力がありません。 好きな味を選んでください>h 選択肢にありません。 好きな味を選んでください>c 選んだのはチョコレートですね。
意図的に入力しなかったり選択肢にない文字を入力しました。でも警告のメッセージが表示され正しい選択をするように誘導されているのがわかります。