実行時にコンソールから入力値を与える（Scanner,BufferedReader）（学習メモ）

### **コンソール画面で入力した値を扱う方法**

Javaでコンソールから自分で任意の値（文字や数字）を引き渡す。私が最初に覚えたScannerクラスとは別に、BufferedReaderというストリーム（Stream）というものもあるので使用例をメモ。

両方の使用例は以下のとおり。※どちらも入力はコンソール

~~~java:例１　Scanner使用例
import java.util.Scanner;
//中略
public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    System.out.print("任意の値xを入力ください：");
    String xIn = scanner.next();
    int x = Integer.parseInt(xIn);//String⇒int変換
    System.out.println("xの2倍は" + (x * 2));
}
~~~
~~~:結果
任意の値xを入力ください：3
xの2倍は6
~~~

Scannerはscanner.next()で文字列の入力を受け付けることができる。
３など（見た目は）数字でもString型で受け付ける。
scanner.nextInt()とすると、String型ではなくint型のみ受け付けるようにすることもできる。※int型以外を入力するとエラーとなる
使用例１のように数字として扱うためには、String型からint型に変換する操作が必要となる。

~~~java:例２　BufferedReader使用例
import java.io.BufferedReader;
import java.io.IOException;
//中略
public static void main(String[] args) throws IOException{

    BufferedReader br = new BufferedReader(
                            new InputStreamReader(System.in));
    System.out.print("任意の値xを入力ください：");
    String xIn = br.readLine();
    int x = Integer.parseInt(xIn);
    System.out.println("xの2倍は" + (x * 2));	
}
~~~
~~~:結果
任意の値xを入力ください：3
xの2倍は6
~~~

例１と同じようにxを２倍にして出力するプログラム。
Scannerと比べてコード量が若干増えた。
また、BufferedReaderの方は以下の点を考慮しておく必要がある。

- #### IOExceptionをスロー（throw）させる必要がある
BufferedReaderはファイル入力やDB入力などにも使えるようなのでファイルが存在しないケースやアクセス権限不足によりファイルを開けない可能性があるので記述が必須。
- #### BufferedReaderの内部にInputStreamReaderをラップすることを推奨
もはやInputStreamReaderとBufferdReaderはセットで使うと覚えた方がよいのだろうか。公式ドキュメントによると、「バッファリングせずにread()、readLine()を使うと、呼び出しごとにファイルからバイトを読み込み、文字型に変換し、そのたびに復帰するので、非常に効率が悪くなります」とのこと。メモリ（RAM）にキャッシュ（一時保存）することで（バッファリングすることで）パフォーマンスが良くなる。

他にも性能面ではScanner < BufferedReaderらしいです。
＜2024/5/24 追記＞
AtCorderに初チャレンジ。A問題でBufferedReaderとscannerの両方を使って同じ問題を解いたところ、以下の違いがあった。
~~~:ScannerとBufferedReaderのパフォーマンス比較結果
#Scanner
処理時間：77 ms
メモリ使用量：38036 KB

#BufferedReader
処理時間：40 ms
メモリ使用量：33960 KB
~~~
~~~java:（参考）比較に使ったコード（Scanner使用）
import java.io.IOException;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) throws IOException{		
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		
		String[] arrayBuildings = new String[n];
		for(int i=0; i < n; i++) {
			arrayBuildings[i] = scanner.next();
		}		
				
		int max = -1;
		for(int i=1; i < n; i++) {
			if(Integer.valueOf( arrayBuildings[0] ) < Integer.valueOf( arrayBuildings[i]) ) {
				max = i+1;
				break;
			}
		}
		System.out.println(max);
	}
}
~~~
~~~java:（参考）比較に使ったコード（BufferedReader使用）
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(
								new InputStreamReader(System.in));
		int n = Integer.parseInt(br.readLine());
		String[] arrayBuildings = br.readLine().split(" ");
				
		int max = -1;
		for(int i=1; i < n; i++) {
			if(Integer.valueOf( arrayBuildings[0] ) < Integer.valueOf( arrayBuildings[i]) ) {
				max = i+1;
				break;
			}
		}
		System.out.println(max);
	}	
}
~~~
補足：atcorderの問題は、N 個のビルが横一列に並んでいて、左からi 番目のビルの高さはHiです。左から1 番目のビルより高いビルが存在するか判定し、存在する場合その内最も左のビルは左から何番目か求めてください。
入力例１）
3
3 4 5
出力例）
2

-------------------
最終更新日：2024.5.24