Java Scanner 类是 java.util 包的一部分,它在 Java 1.5 版中被引入,主要用于接收用户输入,并将其解析成原始数据类型,如 int、double 或 default String。
Java 扫描师类建设者
如果你看看扫描师类,那么有很多构建者。
大多数建设者使用三种对象之一:
- InputStream - 最常见的,我们通过System.in接收用户输入
- 文件或路径 - 我们也可以扫描文件数据,并使用来自文件的值
- 字符串 - 我们也可以为字符串源创建扫描器,并从中解析值
如果您查看第二个参数,则要指定字符集,如果您不希望使用默认字符集进行解析。
扫描师类的重要方法
让我们来看看一些最常用的扫描仪类方法。
- 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