Java中的Scanner类
Java的Scanner类是java.util包的一部分。它在Java 1.5版本中被引入。Scanner主要用于接收用户输入并将其解析为原始数据类型,如int,double或默认字符串。它是一个使用正则表达式生成标记来解析数据的实用类。
Java Scanner Class Constructors – Java Scanner类的构造函数
如果你看一下Scanner类,有很多构造函数。
大多数建筑者都使用三个对象中的一个。
-
- InputStream – 最常见的方式是将 System.in 作为参数传入以接收用户输入。
-
- File 或者 Path – 我们也可以扫描文件数据并处理文件中的值。
- String – 我们也可以为字符串来源创建扫描器,并解析其中的值。
如果你看第二个参数,它是用于指定字符集的,如果你不想使用默认字符集进行解析。
Scanner类的重要方法
让我们来看一下最常用的Scanner类方法。
- useDelimiter(String pattern) – the delimiter to be used for the scanner. The default delimiter is whitespace.
- hasNext() – returns true if there is another token in the input. It’s a blocking method and it will keep waiting for user input.
- next() – returns the next token from the scanner. It’s used in conjunction with the hasNext() method.
- close() – scanner is resource heavy, so once you are done with it, use this method to close it and release system resources.
有许多实用方法可以检查和直接解析输入令牌为int、short、long、byte、BigDecimal等的值。
初始化和使用扫描仪的步骤
-
- 第一步是通过使用适当的构造函数初始化扫描器类,根据输入类型选择InputStream、File或String。如果需要,设置分隔符和字符集。
-
- 第二步是使用hasNext()方法等待输入的标记。
- 然后使用next()方法读取标记并逐个处理它们。
扫描仪是如何工作的? shì de?)
- The Scanner class breaks its input into tokens using the specified delimiter pattern.
- The next() methods is used to read the tokens one by one and process them.
- Finally, close the Scanner instance to release the system resources.
扫描器示例
让我们来看一下Scanner类的一些常见用法和示例代码片段。
1. 阅读用户输入
这是Scanner类最常见的用法。我们可以通过使用System.in作为输入源来实例化并读取用户输入。
// read user input
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
现在你一定明白了,这是因为空格是分隔符。扫描器将输入分成两个令牌 – Pankaj和Kumar。但是,我们只调用了一次next()方法,所以只打印了“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();
使用扫描器解析文件数据。
让我们看一个简单的例子,使用Scanner类来读取和解析CSV文件。假设我有一个名为employees.csv的文件,内容如下。
1,Jane Doe,CEO
2,Mary Ann,CTO
3,John Lee,CFO
让我们在我们的Java程序中读取文件并获取一个员工列表。
package com.Olivia.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 + "]";
}
}
- The first step is to create the scanner for the CSV file and set newline as delimiter.
- Then for each line that contains employee record in CSV format, parse it using another scanner and comma as delimiter. The parseEmployeeData() is parsing each line and creating Employee object.
- Finally, we are adding the employee object to the list and printing it.
输出:[员工[1, 简朵, 首席执行官], 员工[2, 玛丽安, 首席技术官], 员工[3, 约翰李, 首席财务官]]
3. Java 正则表达式的 Scanner 示例
假设我们有一个字符串source,我们想要处理其中的整数。我们可以使用带有非数字正则表达式的扫描器,以获取只有整数作为处理对象的标记。
//using regex to read only integers from a string source
String data = "1a2b345c67d8,9#10";
Scanner sc1 = new Scanner(data);
// setting non-digit regex as delimiter
sc1.useDelimiter("\\D");
while(sc1.hasNext()) {
System.out.println(sc1.next());
}
// don't forget to close the scanner
sc1.close();
输出:
1
2
345
67
8
9
10
结论
Java Scanner是一个用于读取用户输入或处理基于正则表达式的文件或字符串源的实用类。然而,在实际应用中,最好使用CSV解析器来解析CSV数据,而不是使用Scanner类以获得更好的性能。
参考:API文档,Java中的正则表达式