Javaの標準入力まとめ|Scanner・BufferedReaderの使い方と違い、競プロ向け高速入力まで解説

目次

1. この記事で分かること

Javaで「標準入力(System.in)」を扱う方法は複数ありますが、結論はシンプルです。目的に合った手段を選べばOKで、最初から難しい最適化を覚える必要はありません。

この記事では、初心者がつまずきやすいポイントを避けながら、次の3段階で理解できるように解説します。

  • まず動かす(学習・小規模)Scanner
  • 少し本格的に(大量入力・実務寄り)BufferedReader
  • 入力が超多い(競プロ・高速化)FastScanner(高速入力テンプレ)

1.1 迷ったらどれ?用途別の最短結論(Scanner/BufferedReader/高速入力)

ここだけ読めば、あなたが今どれを使えばいいか判断できます。

1) 初心者・学習中・入力が少ない → Scanner

  • 例:学校の課題、学習サイトの練習問題、簡単なツール
  • 強み:コードが短くて分かりやすい/説明もしやすい
  • 注意:入力が多いと遅くなりやすい(競プロだとTLEの原因になりがち)

こんなときはScannerで十分

  • 1行〜数十行程度
  • 速度よりも「理解」と「実装の楽さ」を優先したい

2) 入力が多い・処理を安定させたい → BufferedReader

  • 例:ログっぽい大量の入力、業務のバッチ処理、練習問題でも入力が多め
  • 強み:速い/「行」として読みやすい/自分でパースするので挙動が明確
  • 注意:数値変換(parseInt 等)や分割(StringTokenizer 等)を自分で書く必要がある

BufferedReaderが向く目安

  • 数千行〜それ以上
  • 「速度」と「制御のしやすさ」を両立したい

3) 競プロ・超大量入力 → FastScanner(高速入力)

  • 例:入力が何万〜何十万要素、制限時間がシビア
  • 強み:最速クラス/TLE回避に効く
  • 注意:実装が読みにくくなりがち(テンプレ化して使うのが一般的)

FastScannerが必要になりやすいケース

  • 大量の整数を読み続ける問題
  • Scannerだと明らかに遅いと感じる(またはTLEした)

1.2 この記事の対象読者(初心者〜競プロまで)

この記事は、次のような人を対象にしています。

初心者の方

  • 「標準入力って何?」から知りたい
  • とりあえず キーボード入力を受け取れるようになりたい
  • Scanner の基本を、落とし穴も含めて押さえたい

ある程度書ける方(中級手前)

  • Scanner は使えるけど、入力が多いと遅くなる理由が知りたい
  • BufferedReader を使った書き方(分割・数値変換)を整理したい
  • EOF(入力終端)まで読むパターンも知りたい

競技プログラミングをやる方

  • BufferedReader より速い方法(FastScanner)を使いたい
  • 速度比較の考え方や、テンプレの使い分けを知りたい

1.3 この記事を読み終えたらできるようになること

この記事を最後まで読むと、次のことができるようになります。

  • Javaで 標準入力(System.in)を使った入力処理を、目的に応じて選べる
  • Scanner の基本操作と、よくある落とし穴(入力のズレ)を回避できる
  • BufferedReader で、行入力・スペース区切り入力・数値変換が書ける
  • 入力が膨大なときに、競プロ向けの高速入力(FastScanner)を使える
  • 「なぜ動かない?」「なぜ遅い?」を、原因別に切り分けられる

1.4 次のセクションでやること

次のセクションでは、そもそも 「標準入力」 が何なのかを、System.in の意味からやさしく整理します。
ここが曖昧なままだと、ScannerやBufferedReaderの違いも理解しにくいので、まず土台を作っていきます。

2. Javaの「標準入力」とは

このセクションでは、Javaでよく出てくる 「標準入力」 という言葉の意味を、仕組みレベルで噛み砕いて説明します。
ここを理解しておくと、後で登場する ScannerBufferedReader の役割がはっきり見えてきます。

2.1 標準入力(System.in)の位置づけ

Javaにおける標準入力とは、プログラムが外部からデータを受け取るための“入口”です。
その正体が System.in です。

System.in

これは「キーボード専用」ではありません。
正確には次のような意味を持ちます。

  • プログラム起動時に与えられる入力ストリーム
  • OSが用意した「入力元」を、Javaから参照するためのもの
  • 型は InputStream

つまり、

「どこから入力されるか」は、Java側では決まっていない

という点が重要です。

2.2 標準入力はキーボードとは限らない

初心者が最初につまずきやすい誤解がこれです。

標準入力 = キーボード入力

これは 半分正解で、半分不正解 です。

たしかに、次のように実行すればキーボード入力になります。

java Main

しかし、次のような実行も可能です。

java Main < input.txt

この場合、

  • キーボードではなく
  • input.txt の中身が
  • System.in に流し込まれます

プログラム側は
「キーボードかファイルか」を一切意識しません。

System.in = 入力の“流れ”そのもの
と理解すると混乱しません。

2.3 System.in はそのままでは使いにくい

System.in は便利そうに見えますが、実はそのままでは非常に扱いにくいです。

理由は単純で、System.inバイト単位 でしかデータを扱えないからです。

InputStream in = System.in;

この状態では、

  • 文字列
  • 数値
  • スペース区切り

といった概念は存在しません。

「1行読む」「整数を読む」という操作は
Java標準では用意されていない

そこで登場するのが、System.in を包み込むクラスです。

2.4 標準入力を扱うクラスの役割分担

ここで、全体像を整理しておきます。

入力処理の階層構造(イメージ)

[ 入力元(キーボード / ファイル / パイプ) ]
                ↓
           System.in(InputStream)
                ↓
      入力を扱いやすくするクラス
        ├ Scanner
        ├ BufferedReader
        └ 高速入力クラス(FastScannerなど)

それぞれの役割は次の通りです。

  • System.in
    • 入力の生データ(バイト列)
    • 人間には扱いにくい
  • Scanner
    • 「整数」「文字列」として読み取れる
    • 非常に分かりやすいが、処理は重め
  • BufferedReader
    • 「1行ずつ」高速に読み取れる
    • 自分で分割・変換する必要がある

この構造を理解しておくと、

  • なぜ Scanner が遅いのか
  • なぜ BufferedReader が速いのか

が、感覚ではなく 構造的に理解 できます。

2.5 なぜ複数の入力方法が存在するのか

Javaに標準入力の方法が複数ある理由は、用途が違うからです。

  • 学習用・小規模
    → 分かりやすさ最優先
  • 実務・大量データ
    → 安定性・速度重視
  • 競技プログラミング
    → とにかく速さが最優先

Javaは、
「初心者にも、プロにも使われる言語」
なので、1つの方法だけでは足りません。

その結果、

  • 簡単だが遅い方法
  • 少し手間だが速い方法
  • 可読性を犠牲にした最速手段

が共存しています。

3. 標準入力の代表的な方法(全体像)

ここからは、Javaで標準入力を扱う代表的な3つの方法を、実装に入る前に俯瞰して整理します。
先に全体像を掴んでおくことで、「なぜこの方法を選ぶのか」が明確になります。

3.1 Scanner:最も手軽で学習向き

Scanner は、Java初心者が最初に触れることの多い標準入力クラスです。

Scanner sc = new Scanner(System.in);

この1行で、

  • 文字列
  • 整数
  • 浮動小数点数

といった値を、そのままの型で受け取れます。

Scannerの特徴

  • メリット
    • コードが短い
    • 直感的で分かりやすい
    • 入門書や学習サイトでよく使われている
  • デメリット
    • 内部処理が重く、入力が多いと遅くなりやすい
    • 入力の扱いに独特のクセがある(後述)

向いているケース

  • Javaを学び始めたばかり
  • 入力行数が少ない
  • 可読性・理解を最優先したい

「まず動かす」段階では、Scannerは非常に優秀です。

3.2 BufferedReader:高速で安定した定番手法

BufferedReader は、実務や中級者以上で定番となる標準入力の方法です。

BufferedReader br = new BufferedReader(
    new InputStreamReader(System.in)
);

Scannerと違い、**基本は「1行ずつ読む」**という考え方になります。

BufferedReaderの特徴

  • メリット
    • 入力が速い
    • 挙動が安定している
    • 大量入力でもパフォーマンスが落ちにくい
  • デメリット
    • 数値変換や分割処理を自分で書く必要がある
    • 初心者には少しとっつきにくい

向いているケース

  • 入力が多い
  • 処理時間を意識したい
  • 実務や提出課題など、安定性が重要

「多少コードが長くなっても、確実に動かしたい」
そんな場面で選ばれます。

3.3 競プロ向け:FastScanner(高速入力)

競技プログラミングの世界では、
BufferedReaderですら遅い 場合があります。

そこで使われるのが、FastScanner と呼ばれる高速入力クラスです。

  • BufferedInputStream
  • byte[] バッファ
  • 手動パース

などを組み合わせ、限界まで入力速度を高めます

FastScannerの特徴

  • メリット
    • 非常に高速
    • 大量の数値入力に強い
  • デメリット
    • 実装が読みにくい
    • 初心者には理解が難しい
    • バグるとデバッグが大変

向いているケース

  • 競技プログラミング
  • 入力サイズが極端に大きい問題
  • ScannerでTLE(時間切れ)した経験がある

通常のアプリ開発では、ここまでの高速化はほぼ不要です。

3.4 それぞれの違いを一目で比較

方法分かりやすさ速度主な用途
Scanner学習・小規模
BufferedReader実務・大量入力
FastScanner◎◎競技プログラミング

この表を頭に入れておけば、「どれを使えばいいか」で迷う時間を大幅に減らせます。

3.5 どれを選ぶべきか迷ったときの考え方

迷ったら、次の順で考えると失敗しません。

  1. 入力量は多いか?
    • 少ない → Scanner
    • 多い → BufferedReader
  2. 制限時間がシビアか?
    • No → BufferedReader
    • Yes → FastScanner

多くの場合、
Scanner → BufferedReader の順でステップアップすれば十分です。

4. Scannerで標準入力を受け取る(基本〜実務のコツ)

このセクションでは、Java初心者が最初に使うことの多い Scanner を使った標準入力について、
「書き方」だけでなく なぜそうなるのか まで含めて解説します。

4.1 文字列を受け取る(nextLine)

まずは、最も基本となる 1行の文字列入力 です。

Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
System.out.println(line);
  • nextLine()
    → 改行までを 1行として読み取る

ユーザーが

Hello Java

と入力すれば、line には "Hello Java" がそのまま入ります。

ポイント

  • スペースを含んだ入力でも問題なく取得できる
  • 改行が入力の区切りになる

4.2 数値を受け取る(nextInt / nextLong など)

Scannerは、数値を直接読み取れる点が大きな特徴です。

int n = sc.nextInt();
long x = sc.nextLong();
double d = sc.nextDouble();

これにより、

10

と入力すれば、n には 10(int型)が入ります。

Scannerが便利な理由

  • Integer.parseInt() のような変換が不要
  • 型を意識せずに入力できる

学習段階では、この手軽さが非常に助けになります。

4.3 【重要】nextIntの後にnextLineが空になる問題

Scannerで最も有名な落とし穴がこれです。

int n = sc.nextInt();
String s = sc.nextLine();

このコードを実行すると、s空文字 になることがあります。

なぜ起きるのか

原因は、nextInt()

  • 数値だけを読み取り
  • 改行を読み捨てない

からです。

つまり入力が

10\n

だった場合、

  • nextInt()10 を読む
  • nextLine() → 残っていた \n を読む

結果として、空行を読んだことになります。

解決方法(定番)

int n = sc.nextInt();
sc.nextLine();   // 改行を消費
String s = sc.nextLine();

「数値入力のあとに空の nextLine を1回入れる」
これが鉄板パターンです。

4.4 スペース区切り入力を受け取る

次のような入力を考えます。

10 20 30

Scannerでは、次のように簡単に処理できます。

int a = sc.nextInt();
int b = sc.nextInt();
int c = sc.nextInt();

Scannerは、空白や改行を自動的に区切りとして扱うため、
入力形式を強く意識する必要がありません。

便利だが注意点もある

  • 内部で正規表現を使っている
  • 大量入力では処理が重くなる

これが、Scannerが遅くなりやすい理由の一つです。

4.5 EOF(入力終端)まで読み取る方法

ファイル入力やオンラインジャッジでは、
入力の終わり(EOF)まで読む必要がある場合があります。

while (sc.hasNext()) {
    int x = sc.nextInt();
    System.out.println(x);
}

または、行単位なら次のように書けます。

while (sc.hasNextLine()) {
    String line = sc.nextLine();
    System.out.println(line);
}

使い分けの目安

  • 数値中心 → hasNext()
  • 行単位 → hasNextLine()

4.6 Scannerはなぜ遅くなりやすいのか

Scannerが遅い理由は、主に次の点にあります。

  • 正規表現によるトークン解析
  • 型変換の内部処理が重い
  • 柔軟性を重視した設計

これは 欠点というより設計思想の違い です。

Scannerは
「安全・汎用・分かりやすい」
を優先したクラス

大量入力や速度重視の場面では、別の方法を選ぶのが正解です。

4.7 Scannerを使うべきかどうかの判断基準

Scannerを選んで問題ないのは、次のようなケースです。

  • 入力が少ない
  • 学習・検証目的
  • 処理時間制限が厳しくない

逆に、

  • 数千行以上の入力
  • 競技プログラミング
  • パフォーマンスが重要

といった場合は、次のセクションで解説する
BufferedReader を選びましょう。

5. BufferedReaderで標準入力を受け取る(高速&定番)

このセクションでは、入力が多い場面で定番となる BufferedReader を使った標準入力の扱い方を解説します。
Scannerよりコード量は増えますが、速度・安定性・挙動の分かりやすさで優れています。

5.1 最小コード:readLineで1行読む

BufferedReader は「1行ずつ読む」のが基本です。

BufferedReader br = new BufferedReader(
    new InputStreamReader(System.in)
);

String line = br.readLine();
System.out.println(line);
  • readLine()
    → 改行までを1行として読み取る
  • 入力がなければ null を返す(EOF)

Scannerと違い、行という単位が明確なのが特徴です。

5.2 複数行入力を読むテンプレ(EOFまで)

入力の行数が決まっていない場合は、次の形が定番です。

String line;
while ((line = br.readLine()) != null) {
    System.out.println(line);
}

ポイント

  • null 判定 = 入力の終端(EOF)
  • ファイル入力・オンラインジャッジで頻出
  • 無限ループになりにくい安全な書き方

5.3 数値に変換する方法(parseInt / parseLong)

BufferedReader文字列として読む ため、数値変換は自分で行います。

int n = Integer.parseInt(br.readLine());
long x = Long.parseLong(br.readLine());
double d = Double.parseDouble(br.readLine());

ここが重要

  • 入力が不正だと NumberFormatException が発生
  • Scannerよりも 入力形式を厳密に意識する必要がある

ただし、その分「何を読んで、どう変換したか」が明確になります。

5.4 スペース区切り入力の処理方法

実務・競プロで最も多いのが スペース区切り入力 です。

10 20 30

方法① splitを使う(分かりやすさ重視)

String[] parts = br.readLine().split(" ");
int a = Integer.parseInt(parts[0]);
int b = Integer.parseInt(parts[1]);
int c = Integer.parseInt(parts[2]);
  • 可読性が高い
  • 初心者向け
  • ただし split は内部で正規表現を使うため、やや重い

方法② StringTokenizerを使う(速度重視)

StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
  • split より高速
  • 競技プログラミングでよく使われる
  • やや古風だが今でも現役

使い分けの目安

  • 可読性優先 → split
  • 入力が多い → StringTokenizer

5.5 複数行 × スペース区切り入力の定番パターン

次のような入力形式を想定します。

3
10 20
30 40
50 60
int n = Integer.parseInt(br.readLine());

for (int i = 0; i < n; i++) {
    StringTokenizer st = new StringTokenizer(br.readLine());
    int x = Integer.parseInt(st.nextToken());
    int y = Integer.parseInt(st.nextToken());
    System.out.println(x + y);
}

この形は、

  • 実務
  • アルゴリズム問題
  • 技術試験

で非常によく出てきます。

5.6 IOExceptionの扱い方(初心者が迷う点)

BufferedReader を使うと、例外処理が必要になります。

try {
    BufferedReader br = new BufferedReader(
        new InputStreamReader(System.in)
    );
    String line = br.readLine();
} catch (IOException e) {
    e.printStackTrace();
}

または、main メソッドでまとめて投げる方法もあります。

public static void main(String[] args) throws Exception {
    BufferedReader br = new BufferedReader(
        new InputStreamReader(System.in)
    );
}

どちらを選ぶ?

  • 学習・競プロ → throws Exception で簡潔に
  • 実務 → try-catch で明示的に処理

5.7 BufferedReaderが速い理由

BufferedReaderが速い理由は、次の2点です。

  1. 内部でまとめて読み込む(バッファリング)
  2. 正規表現などの重い解析をしない

つまり、

「読む → 解釈する」を
自分で制御できる

これが、Scannerとの決定的な違いです。

5.8 Scannerとの違いを整理

観点ScannerBufferedReader
分かりやすさ
入力速度
行入力
数値変換自動手動
実務向き

6. 競技プログラミング向け:FastScannerの実装例(最速クラス)

このセクションでは、入力速度がボトルネックになる場面で使われる
FastScanner(高速入力) の考え方と実装例を解説します。

通常のアプリ開発ではほとんど不要ですが、競技プログラミングでは「知っているかどうか」で結果が変わる重要ポイントです。

6.1 なぜScannerではTLE(時間切れ)になるのか

競技プログラミングでは、次のような条件がよくあります。

  • 入力数:数十万〜数百万
  • 制限時間:1〜2秒
  • 実行環境:高速とは限らない

この状況でScannerを使うと、
入力処理だけで時間を使い切ることがあります。

理由は以下の通りです。

  • 正規表現ベースのトークン解析
  • 型変換を内部で安全に行う設計
  • 汎用性重視で余分な処理が多い

つまりScannerは
「競技用途にはオーバースペックで重い」
という位置づけになります。

6.2 BufferedReaderでも足りない場面とは

BufferedReaderは高速ですが、それでも次の処理が残ります。

  • 文字列の生成
  • split / StringTokenizer
  • 数値への変換

入力が極端に多い場合、
この変換処理自体がボトルネックになります。

そこで、

文字列にせず
バイト列のまま
数値として読み取る

という発想が生まれます。

6.3 FastScannerの基本的な考え方

FastScannerは、次の仕組みで高速化します。

  1. BufferedInputStream で一気に読み込む
  2. byte[] バッファに保持
  3. 数字を見つけたら、その場で数値化
  4. 不要なオブジェクト生成をしない

その結果、

  • メモリ確保が減る
  • GC(ガベージコレクション)が減る
  • 処理が安定する

という効果が得られます。

6.4 実用的なFastScanner実装例

以下は、競プロでそのまま使える最小構成の例です。

static class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1 << 16];
    private int ptr = 0, len = 0;

    private int readByte() throws IOException {
        if (ptr >= len) {
            len = in.read(buffer);
            ptr = 0;
            if (len <= 0) return -1;
        }
        return buffer[ptr++];
    }

    int nextInt() throws IOException {
        int c;
        do {
            c = readByte();
        } while (c <= ' ');

        boolean negative = false;
        if (c == '-') {
            negative = true;
            c = readByte();
        }

        int val = 0;
        while (c > ' ') {
            val = val * 10 + (c - '0');
            c = readByte();
        }
        return negative ? -val : val;
    }
}

使い方例

FastScanner fs = new FastScanner();
int n = fs.nextInt();

この形で、大量の整数を高速に読み取れます。

6.5 FastScannerを使う際の注意点

FastScannerは万能ではありません。

注意点

  • コードが読みにくい
  • デバッグが難しい
  • 文字列入力には不向き
  • 実務では過剰最適化になることが多い

そのため、

競技用途以外では使わない

という割り切りが重要です。

6.6 Scanner / BufferedReader / FastScanner の位置づけ

ここまでの内容を整理します。

  • Scanner
    • 学習用・小規模
  • BufferedReader
    • 実務・大量入力
  • FastScanner
    • 競技プログラミング専用

「速い=正解」ではなく、
目的に合った手段を選ぶことが最重要です。

7. 目的別の選び方(迷わない早見表)

ここまでで、Javaの標準入力には複数の方法があり、それぞれ 向いている用途が明確に違う ことが分かりました。

このセクションでは、「結局どれを使えばいいのか」を 即判断できる形 に整理します。

7.1 学習・簡単なツールの場合

おすすめ:Scanner

理由

  • コードが短い
  • 型変換を意識しなくてよい
  • 学習資料が豊富
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();

向いているケース

  • Java学習初期
  • 学校・研修の課題
  • 入力が少ないプログラム

避けた方がよいケース

  • 入力が多い
  • 実行時間制限が厳しい

7.2 入力が多い・安定性を重視したい場合

おすすめ:BufferedReader

理由

  • 入力速度が速い
  • 行単位で制御しやすい
  • 実務でも広く使われている
BufferedReader br = new BufferedReader(
    new InputStreamReader(System.in)
);

向いているケース

  • バッチ処理
  • ログ解析
  • 業務ツール
  • 入力行数が多い課題

ポイント

  • 数値変換や分割は自分で書く
  • 入力形式を正確に把握する

7.3 競技プログラミング・超大量入力の場合

おすすめ:FastScanner

理由

  • 入力処理が最速クラス
  • TLE回避に直結する
FastScanner fs = new FastScanner();
int n = fs.nextInt();

向いているケース

  • 競技プログラミング
  • 数十万〜数百万の入力
  • Scannerで時間切れした経験がある

注意

  • 可読性は犠牲になる
  • 実務では使わないのが無難

7.4 迷ったときの判断フロー

迷ったら、次の順で考えれば失敗しません。

  1. 学習目的か?
    • Yes → Scanner
  2. 入力が多いか?
    • Yes → BufferedReader
  3. 制限時間が非常に厳しいか?
    • Yes → FastScanner

ほとんどのケースは、BufferedReaderで十分 です。

7.5 よくある勘違い

「速い方法を使えば正解」

間違い

  • 可読性が落ちる
  • バグを生みやすい
  • 保守が難しくなる

「Scannerはダメ」

間違い

  • 学習用途では最適
  • 小規模なら全く問題ない

適材適所 が大切です。

8. よくあるエラー/つまずき集(トラブルシュート)

このセクションでは、Javaの標準入力で実際によく起きるトラブルを、「原因 → 対処」の形で整理します。
初心者がつまずきやすい点を事前に知っておくことで、無駄な試行錯誤を減らせます。

8.1 入力したはずなのに値が取得できない

症状

  • 何も入力していないのに処理が進む
  • 文字列が空になる

主な原因

  • nextInt() の後に nextLine() を呼んでいる
  • 改行が残っている

対処法

int n = sc.nextInt();
sc.nextLine(); // 改行を消費
String s = sc.nextLine();

Scanner特有の仕様なので、BufferedReaderに切り替えるのも有効です。

8.2 入力が途中で止まる/無限待ちになる

症状

  • プログラムが入力待ちで止まる
  • オンラインジャッジで実行が終わらない

主な原因

  • 入力形式と読み取り回数が一致していない
  • EOFを考慮していない

対処法

  • 行数が決まっていない場合は EOF を使う
String line;
while ((line = br.readLine()) != null) {
    // 処理
}

入力仕様を必ず確認することが重要です。

8.3 NumberFormatException が発生する

症状

  • 数値変換時に例外が出る
int n = Integer.parseInt(line);

主な原因

  • 空文字や余分な空白が含まれている
  • 想定外の文字が混ざっている

対処法

line = line.trim();
int n = Integer.parseInt(line);

また、分割後の配列インデックスがずれていないかも確認しましょう。

8.4 splitで思った通りに分割されない

症状

  • 配列の要素数が想定と違う
  • 空文字が混ざる

主な原因

  • 連続するスペース
  • 正規表現としての解釈

対処法

String[] parts = line.trim().split("\\s+");

\\s+ を使うと、
空白が1つ以上連続しても正しく分割できます。

8.5 入力は正しいのに遅い(TLE)

症状

  • ローカルでは動くが、提出すると時間切れ

主な原因

  • Scannerを使用している
  • splitを多用している

対処法

  • Scanner → BufferedReader
  • split → StringTokenizer
  • 必要なら FastScanner

「処理が遅い」のではなく、入力処理が原因であるケースは非常に多いです。

8.6 IOException の扱いが分からない

症状

  • コンパイルエラーになる
  • try-catchを書くべきか迷う

対処法(簡潔)

public static void main(String[] args) throws Exception {
    BufferedReader br = new BufferedReader(
        new InputStreamReader(System.in)
    );
}

学習・競プロでは、main に throws Exception で十分です。

8.7 文字化けが発生する場合

症状

  • 日本語が正しく読めない

主な原因

  • 文字コードの不一致

対処法

BufferedReader br = new BufferedReader(
    new InputStreamReader(System.in, "UTF-8")
);

実務やファイル入力では、エンコーディング指定を意識しましょう。

8.8 トラブル時のチェックリスト

問題が起きたら、次を順に確認してください。

  1. 入力形式と読み取りコードは一致しているか
  2. 改行・空白の扱いは正しいか
  3. Scanner特有の仕様を踏んでいないか
  4. 入力が多すぎないか(速度)
  5. EOFを考慮しているか

9. FAQ(よくある質問)

このセクションでは、「java 標準入力」 に関して特に質問されやすい内容を、Q&A形式でまとめます。
検索ユーザーの疑問を一通り解消できる構成です。

9.1 Q1. ScannerとBufferedReaderは結局どちらを使うべきですか?

A. 目的によって使い分けるのが正解です。

  • 学習・入力が少ない → Scanner
  • 入力が多い・安定性重視 → BufferedReader

迷ったら、BufferedReaderを選んでおけば失敗しにくいです。

9.2 Q2. Scannerが遅いと言われるのは本当ですか?

A. 入力が多い場合は本当です。

Scannerは正規表現を使った解析や、安全性重視の設計により、大量入力では処理時間がかかります。

小規模な入力では、体感できる差はほとんどありません。

9.3 Q3. nextIntの後にnextLineが空になるのはなぜですか?

A. 改行が読み残される仕様だからです。

nextInt() は数値だけを読み取り、改行文字は残します。

対策として、

sc.nextLine();

を1回挟むか、BufferedReaderに切り替えましょう。

9.4 Q4. スペース区切り入力は split と StringTokenizer のどちらが良いですか?

A. 入力量で決めるのが現実的です。

  • 少量・可読性重視 → split
  • 大量・速度重視 → StringTokenizer

競技プログラミングでは StringTokenizer がよく使われます。

9.5 Q5. EOF(入力終端)まで読みたいときはどう書けばいいですか?

A. BufferedReaderで null チェックを行います。

String line;
while ((line = br.readLine()) != null) {
    // 処理
}

Scannerの場合は、hasNext()hasNextLine() を使います。

9.6 Q6. FastScannerは実務でも使えますか?

A. 基本的にはおすすめしません。

FastScannerは競技用途に特化しており、

  • 可読性が低い
  • 保守性が悪い
  • バグを生みやすい

というデメリットがあります。

実務では BufferedReader が最適です。

9.7 Q7. 標準入力で例外処理は必須ですか?

A. BufferedReaderを使う場合は必要です。

ただし、

public static void main(String[] args) throws Exception {

と書けば、学習・競プロでは問題ありません。

実務では try-catch を明示的に書きましょう。

9.8 Q8. 入力は速くなったのに、出力が遅いです。対策は?

A. 出力もまとめて行いましょう。

  • System.out.println を多用しない
  • StringBuilder + PrintWriter を使う

入力と出力は、セットで最適化するのが基本です。

10. まとめ

この記事では、Javaの標準入力について、初心者から競技プログラミングまでを想定し、段階的に解説してきました。最後に、重要なポイントだけを整理します。

10.1 結局どうすればいいか(3行まとめ)

  • 学習・小規模入力Scanner
  • 実務・大量入力BufferedReader
  • 競技プログラミングFastScanner

「速い方法を使う」のではなく、用途に合った方法を選ぶことが最も重要です。

10.2 標準入力で迷わなくなる考え方

標準入力で迷う原因の多くは、

  • なぜ複数の方法があるのか
  • どこが違うのか
  • どれが正解なのか

が整理できていないことにあります。

この記事で紹介したように、

  • Scanner:分かりやすさ重視
  • BufferedReader:安定性・速度重視
  • FastScanner:競技特化

役割が明確に分かれている ことを理解すれば、入力処理で悩むことはほとんどなくなります。

10.3 初心者へのおすすめルート

これからJavaを学ぶ場合は、次の順で進むのがおすすめです。

  1. Scannerで入力に慣れる
  2. BufferedReaderで行入力・分割・変換を理解する
  3. 必要になったら FastScannerを知識として押さえる

最初から難しい方法を使う必要はありません。

10.4 実務・競プロでの実践ポイント

  • 入力仕様を必ず確認する
  • 改行・空白の扱いを意識する
  • 入力と出力はセットで最適化する
  • 困ったら「入力が原因では?」と疑う

これだけでも、トラブルや時間切れを大きく減らせます。

10.5 次に読むと理解が深まる内容

標準入力を理解したら、次は以下のテーマがおすすめです。

  • Javaの標準出力(PrintWriter / StringBuilder)
  • 例外処理の基礎
  • コレクション(List / Map)との組み合わせ
  • アルゴリズム問題での入出力設計

Javaの標準入力は、地味ですが非常に重要な基礎です。
ここを正しく理解しておくことで、学習・実務・競技のすべてが楽になります。