你好!
我们今天的课程会很特别!
在以前,完成任务和编写程序的过程很简单:我们编写一些代码,运行 main() 方法,程序做要做的事情,就行了。
但现在一切都将改变。今天我们将学习如何切实与程序互动:我们将教它如何对我们的操作做出反应!
在我们开始分析代码之前,你有没有处理过像扫描仪这样的设备?可能处理过。扫描仪的内部非常复杂,但其工作原理非常简单:读取用户提供的数据(如护照或保单),并将这些信息存储在内存中(例如,以图像的方式)。
今天,我们会创建自己的扫描仪。当然,它不能处理纸质文件,但处理文本不成问题 :)
让我们开始吧!
糟糕。我们有大麻烦了-_-为了避免这种情况,我们需要想出一种方法来验证用户输入的数据。例如,如果用户输入的不是数字,那么最好显示一个警告,说明输入的信息不是数字。如果信息没问题,就可以确认。但这需要我们“展望未来”,看看信息流会显示什么。Scanner 可以实现此功能吗?如何实现!可以采用许多方法来实现此功能:hasNextInt() — 该方法会检查下一个输入数据块是否是数字(根据需要返回 true 或 false)。hasNextLine() — 该方法会检查下一个输入块是否是字符串。hasNextByte(), hasNextShort()、hasNextLong()、hasNextFloat()、hasNextDouble() — 所有这些方法都对其余的数据类型执行类似的检查。现在试试改变数字读取程序:
Java 的 Scanner 类
首先,我们必须熟悉 java.util.Scanner 类。它的功能非常简单。与真正的扫描仪一样,它从你指定的来源读取数据。例如字符串、文件和控制台。接下来,它识别信息并进行相应的处理。下面是最简单的示例:
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner("It matters not how strait the gate,\n" +
"How charged with punishments the scroll,\n" +
"I am the master of my fate,\n" +
"I am the captain of my soul");
String s = scanner.nextLine();
System.out.println(s);
}
}
我们已经创建了一个扫描仪对象,并指定了它的数据源(文本字符串)。nextLine() 方法访问数据源(即含四行诗的文本),找到下一个未读的行(在本例中是第一行),再将其返回。然后在控制台上显示出来:控制台输出:
It matters not how strait the gate,
我们可以多次使用 nextLine() 方法并显示整个诗的摘录:
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner("It matters not how strait the gate,\n" +
"How charged with punishments the scroll,\n" +
"I am the master of my fate,\n" +
"I am the captain of my soul");
String s = scanner.nextLine();
System.out.println(s);
s = scanner.nextLine();
System.out.println(s);
s = scanner.nextLine();
System.out.println(s);
s = scanner.nextLine();
System.out.println(s);
}
}
我们的扫描仪每次前进一步,读取下一行。该程序的输出显示如下:
It matters not how strait the gate,
How charged with punishments the scroll,
I am the master of my fate,
I am the captain of my soul
正如我们已经说过的,扫描仪的数据源不一定是字符串。例如,数据源可能是控制台。好消息是,以前,我们只显示数据,但现在将从键盘上读取数据!看看 Scanner 类还做了什么:
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number:");
int number = sc.nextInt();
System.out.println("Thanks! You entered the number " + number);
}
}
nextInt() 方法读取并返回输入的数字。在程序中,我们使用该方法将值赋给变量 number。现在它更像一个真实的扫描仪了!程序会请求用户输入任何数字。在用户输完后,程序感谢用户,显示结果,然后结束。但仍存在严重问题。用户可能错误输入了内容。下面是当前程序停止工作的一个例子:
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number:");
int number = sc.nextInt();
System.out.println("Thanks! You entered the number " + number);
}
}
现在尝试输入字符串“CodeGym”而不是数字:控制台输出:
Enter a number:
CodeGym
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at Main.main(Main.java:10) Process finished with exit code 1

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number:");
if (sc.hasNextInt()) {
int number = sc.nextInt();
System.out.println("Thanks! You entered the number " + number);
} else {
System.out.println("Sorry, but this is clearly not a number. Restart the program and try again!");
}
}
}
现在我程序检查下一个输入的字符是否是数字。并且仅当它是数字时才显示确认。如果输入没有通过检查,程序会记录下来并要求用户再试一次。
基本上,你可以与 Scanner 对象通信,提前了解需要输入的数据类型。数字、字符串或其他?数字?什么类型?int、short、long?
这种灵活性使你有机会构建依赖于用户行为的程序逻辑。我们应该注意另一个重要的方法:useDelimiter()。
你将字符串传入此方法。该字符串包含要用作分隔符的字符。
例如,假设我们突然对日本诗歌感兴趣,并决定使用扫描仪读取大诗人松尾芭蕉写的一些俳句。
即使三段不同的诗歌是以一个很难看的字符串形式传递的,我们仍可以轻松拆分并优美呈现出来:
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner("On a withered branch'" +
"A crow has alighted.'" +
"Nightfall in autumn." +
"''***''" +
"Such a moon above,'" +
"Like a tree cut at the root:'" +
"he fresh cut is white." +
"''***''" +
"How the river floods!'" +
"A heron wanders on short legs,'" +
"Knee-deep in the water.");
scan.useDelimiter("'");
while (scan.hasNext()) {
System.out.println(scan.next());
}
scan.close();
}
}
我们使用 "\n/*/*/*"(新行字符和三个星号)作为分隔符。最后,我们得到漂亮的控制台输出,就像在书中一样:
On a withered branch
A crow has alighted.
Nightfall in autumn.
***
Such a moon above,
Like a tree cut at the root:
The fresh cut is white.
***
How the river floods!
A heron wanders on short legs,
Knee-deep in the water.
此示例还有一个方法必须提出来:close()。像任何处理 I/O 流的对象一样,扫描仪在完成后必须关闭,这样它就不会消耗计算机的资源。绝不要忘记使用 close() 方法!
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number:");
int number = sc.nextInt();
System.out.println("Thanks! You entered the number " + number);
sc.close(); // Now we've done everything right!
}
}
今天就讲到这里!正如你所见,Scanner 类很有用,可轻松使用!:)
GO TO FULL VERSION