Java 中的扫描仪类

Java Scanner 类是 java.util 包的一部分,它在 Java 1.5 版中被引入,主要用于接收用户输入,并将其解析成原始数据类型,如 int、double 或 default String。

Java 扫描师类建设者

如果你看看扫描师类,那么有很多构建者。

Scanner Class Constructors

大多数建设者使用三种对象之一:

  1. InputStream - 最常见的,我们通过System.in接收用户输入
  2. 文件或路径 - 我们也可以扫描文件数据,并使用来自文件的值
  3. 字符串 - 我们也可以为字符串源创建扫描器,并从中解析值

如果您查看第二个参数,则要指定字符集,如果您不希望使用默认字符集进行解析。

扫描师类的重要方法

让我们来看看一些最常用的扫描仪类方法。

  • useDelimiter(String pattern) - 将用于扫描仪的界限器. 默认的界限器是whitespace.
  • hasNext() - 返回如果输入中有另一个代币是真的. 这是一个封锁方法,它将继续等待用户输入
  • next() - 返回来自扫描仪的下一个代币。 它与 hasNext()方法
  • close()一起使用 - 扫描仪是资源沉重的,所以一旦完成,使用此方法来关闭它并释放系统资源

有许多实用方法来检查和直接解析输入代币在int、短、长、字节、BigDecimal等。

启动和使用扫描仪的步骤

第一步是使用基于输入类型(如 InputStream、File 或 String)的相应构建器初始化扫描仪类别,如有必要,设置分界器和字符集以使用 2。第二步是使用 hasNext() 方法等待输入代币 3。

扫描仪是如何工作的?

  • 扫描师类将其输入分割到使用指定的分界器模式的代币中
  • 使用下一个() 方法来逐一读取代币并处理它们
  • 最后,关闭扫描师实例以释放系统资源

扫描仪示例

让我们看看使用样本代码片段的扫描仪类的一些常见用途。

1、阅读用户输入

这是 Scanner 类最常用的用途,我们可以使用 System.in 作为输入源进行实例化,并读取用户输入。

1// read user input
2Scanner sc = new Scanner(System.in);
3System.out.println("Please enter your name");
4String name = sc.next();
5System.out.println("Hello " + name);
6sc.close();

输出:

1Please enter your name
2Pankaj
3Hello Pankaj

好吧,它看起来很简单,工作很好,但是,上面的代码有一个问题. 没有阅读下一节,你可以检查代码并尝试识别它吗?

让我们看看当我在输入中写下我的全名时会发生什么。

1Please enter your name
2Pankaj Kumar
3Hello Pankaj

现在你必须得到它,它正在发生,因为白空间是界限器. 扫描仪正在将输入分解成两个代币 - Pankaj 和 Kumar. 但,我们只打电话到下一个() 方法一次,所以只打印了Hello Pankaj

我们如何修复这一点?

我们可以通过使用Delimiter() 方法将分界符更改为 newline 字符。

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

2、使用扫描仪分析文件数据

让我们来看看一个简单的例子,用扫描仪类读取和解析 CSV 文件. 假设我有一个 employees.csv 文件,包含以下内容。

11,Jane Doe,CEO
22,Mary Ann,CTO
33,John Lee,CFO

让我们阅读文件,并在我们的Java程序中获得员工列表。

 1package com.journaldev.java;
 2
 3import java.io.File;
 4import java.io.IOException;
 5import java.util.ArrayList;
 6import java.util.List;
 7import java.util.Scanner;
 8
 9public class ScannerExamples {
10
11    public static void main(String[] args) throws IOException {
12
13    	// create scanner for the CSV file
14    	Scanner sc = new Scanner(new File("employees.csv"));
15
16    	// set delimiter as new line to read one line as a single token
17    	sc.useDelimiter(System.getProperty("line.separator"));
18
19    	// create the List of Employees
20    	List<Employee> emps = new ArrayList<>();
21
22    	while (sc.hasNext()) {
23    		Employee emp = parseEmployeeData(sc.next());
24    		emps.add(emp);
25    	}
26
27    	// close the scanner
28    	sc.close();
29
30    	// print employee records
31    	System.out.println(emps);
32    }
33
34    private static Employee parseEmployeeData(String record) {
35    	// create scanner for the String record
36    	Scanner sc = new Scanner(record);
37
38    	// set delimiter as comma
39    	sc.useDelimiter(",");
40
41    	Employee emp = new Employee();
42    	emp.setId(sc.nextInt());
43    	emp.setName(sc.next());
44    	emp.setRole(sc.next());
45
46    	// close the scanner
47    	sc.close();
48
49    	return emp;
50    }
51
52}
53
54class Employee {
55    private int id;
56    private String name;
57    private String role;
58
59    public int getId() {
60    	return id;
61    }
62
63    public void setId(int id) {
64    	this.id = id;
65    }
66
67    public String getName() {
68    	return name;
69    }
70
71    public void setName(String name) {
72    	this.name = name;
73    }
74
75    public String getRole() {
76    	return role;
77    }
78
79    public void setRole(String role) {
80    	this.role = role;
81    }
82
83    @Override
84    public String toString() {
85    	return "Emp[" + id + "," + name + "," + role + "]";
86    }
87}
  • 第一步是为 CSV 文件创建扫描仪,并将新行设置为分界线
  • 然后对于每个包含 CSV 格式的员工记录的行,使用另一个扫描仪和 comma 作为分界线进行解析。

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

Java Scanner 常规表达式示例

假设我们有一个字符串源,我们只想处理存在的整数,我们可以使用与非数字 regex 的扫描仪来获得只有整数作为代币来处理它们。

 1//using regex to read only integers from a string source
 2String data = "1a2b345c67d8,9#10";
 3Scanner sc1 = new Scanner(data);
 4
 5// setting non-digit regex as delimiter
 6sc1.useDelimiter("\\D");
 7
 8while(sc1.hasNext()) {
 9    System.out.println(sc1.next());
10}
11
12// don't forget to close the scanner
13sc1.close();

输出:

11
22
3345
467
58
69
710

结论

Java Scanner 是一个用于读取用户输入或处理简单的基于 regex 的文件或字符串源解析的实用类,但对于现实世界的应用程序,最好使用 CSV 解析器来解析 CSV 数据,而不是使用 Scanner 类以获得更好的性能。

** 参考**: API Doc, Regex in Java

Published At
Categories with 技术
Tagged with
comments powered by Disqus