JavaでのScannerクラス

JavaのScannerクラスはjava.utilパッケージの一部です。これはJava 1.5リリースで導入されました。Scannerは主にユーザーの入力を受け取り、それらをint、double、またはデフォルトのStringなどのプリミティブデータ型に解析するために使用されます。これは、正規表現を使用してトークンを生成してデータを解析するためのユーティリティクラスです。

Java Scannerクラスのコンストラクタ

Scannerクラスを見ると、多くのコンストラクタがあります。

Scanner Class Constructors

ほとんどのコンストラクタは、次の3つのオブジェクトのいずれかを使用しています:

  1. InputStream – 最も一般的なのは、System.inを渡してユーザーの入力を受け取る場合です。
  2. FileまたはPath – ファイルデータをスキャンし、ファイルからの値と連携することができます。
  3. String – 文字列ソース用のスキャナを作成し、その値を解析できます。

2番目の引数を見ると、デフォルトの文字セットを使用したくない場合は、文字セットを指定するためのものです。

Scannerクラスの重要なメソッド

いくつかの一般的に使用されるScannerクラスのメソッドを見てみましょう。

  • useDelimiter(String pattern) – スキャナに使用するデリミタ。デフォルトのデリミタは空白です。
  • hasNext() – 入力に別のトークンがある場合はtrueを返します。これはブロッキングメソッドであり、ユーザーの入力があるまで待機します。
  • next() – スキャナーから次のトークンを返します。これはhasNext()メソッドと組み合わせて使用されます。

close() – スキャナーはリソースを多く消費するため、使用が完了したらこのメソッドを使用して閉じ、システムリソースを解放します。

スキャナーの初期化と使用手順

  1. 最初のステップは、入力タイプ(InputStream、File、またはString)に基づいて適切なコンストラクタを使用してスキャナークラスを初期化することです。必要に応じて区切り記号と使用する文字セットを設定します。
  2. 2番目のステップは、hasNext()メソッドを使用して入力トークンを待機することです。
  3. その後、next()メソッドを使用してトークンを読み取り、それらを1つずつ処理します。

Scannerの動作は?

  • Scannerクラスは、指定された区切りパターンを使用して入力をトークンに分割します。
  • next()メソッドはトークンを1つずつ読み取り、それらを処理するために使用されます。
  • 最後に、Scannerインスタンスを閉じてシステムリソースを解放します。

Scannerの例

いくつかの一般的なScannerクラスの使用例を見てみましょう。サンプルコードを含みます。

1. ユーザー入力の読み取り

これは、Scannerクラスの最も一般的な使用法です。入力ソースとしてSystem.inを使用して、ユーザー入力を読み取ることができます。

// ユーザー入力を読み取る
Scanner sc = new Scanner(System.in);
System.out.println("Please enter your name");
String name = sc.next();
System.out.println("Hello " + name);
sc.close();

出力:

Please enter your name
Pankaj
Hello Pankaj

まあ、簡単そうで問題なく動作していますね。ただし、上記のコードには問題があります。次のセクションを読まずに、コードを確認して問題を特定できますか?

入力にフルネームを入力するとどうなるか見てみましょう。

Please enter your name
Pankaj Kumar
Hello Pankaj

これでわかるはずです。スペースが区切り文字として使用されているためです。スキャナは入力を2つのトークンに分割しています – PankajとKumar。しかし、next()メソッドを1回しか呼び出していないため、「Hello Pankaj」しか印刷されません。

これを修正するには?

簡単です。useDelimiter()メソッドを使用して区切り文字を改行文字に変更できます。

Scanner sc = new Scanner(System.in);
sc.useDelimiter(System.getProperty("line.separator"));
System.out.println("Please enter your name");
String name = sc.next();
System.out.println("Hello " + name);
sc.close();

2. スキャナーを使用したファイルデータの解析

Scannerクラスを使用してCSVファイルを読み取り、解析する簡単な例を見てみましょう。次の内容を持つemployees.csvファイルがあるとします。

1,Jane Doe,CEO
2,Mary Ann,CTO
3,John Lee,CFO

ファイルを読み取り、Javaプログラムで従業員のリストを取得しましょう。

package com.journaldev.java;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class ScannerExamples {

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

		// create scanner for the CSV file
		Scanner sc = new Scanner(new File("employees.csv"));

		// set delimiter as new line to read one line as a single token
		sc.useDelimiter(System.getProperty("line.separator"));

		// create the List of Employees
		List<Employee> emps = new ArrayList<>();

		while (sc.hasNext()) {
			Employee emp = parseEmployeeData(sc.next());
			emps.add(emp);
		}

		// close the scanner
		sc.close();

		// print employee records
		System.out.println(emps);
	}

	private static Employee parseEmployeeData(String record) {
		// create scanner for the String record
		Scanner sc = new Scanner(record);

		// set delimiter as comma
		sc.useDelimiter(",");

		Employee emp = new Employee();
		emp.setId(sc.nextInt());
		emp.setName(sc.next());
		emp.setRole(sc.next());

		// close the scanner
		sc.close();

		return emp;
	}

}

class Employee {
	private int id;
	private String name;
	private String role;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getRole() {
		return role;
	}

	public void setRole(String role) {
		this.role = role;
	}

	@Override
	public String toString() {
		return "Emp[" + id + "," + name + "," + role + "]";
	}
}
  • // CSVファイルのためのスキャナーを作成
  • // 改行を区切り文字として設定して、1行を単一のトークンとして読み取る
  • // 従業員のリストを作成

// スキャナーを閉じる

// 従業員レコードを出力

// 文字列レコードのためのスキャナーを作成

// 区切り文字をコンマに設定
String data = "1a2b345c67d8,9#10";
Scanner sc1 = new Scanner(data);

// スキャナーを閉じる
sc1.useDelimiter("\\D");

while(sc1.hasNext()) {
	System.out.println(sc1.next());
}

最初のステップは、CSVファイルのためのスキャナーを作成し、改行を区切り文字として設定することです。
sc1.close();

CSV形式で従業員レコードを含む各行について、別のスキャナーとコンマを区切り文字として解析します。 parseEmployeeData() は、各行を解析して従業員オブジェクトを作成しています。

1
2
345
67
8
9
10

最後に、従業員オブジェクトをリストに追加し、それを出力しています。

出力: [Emp[1,Jane Doe,CEO], Emp[2,Mary Ann,CTO], Emp[3,John Lee,CFO]]

3. Java Scanner 正規表現の例

Source:
https://www.digitalocean.com/community/tutorials/scanner-class-in-java