Java 查缺补漏

Java Scanner

java.util.Scanner 是 Java5 的新特征,我们可以通过 Scanner 类来获取用户的输入。ACM 模式必备。

注意:JUnit 的测试方法(如@Test)默认不会连接控制台(System.in),一定要在main()方法中运行。

Scanner 类的UML 图如下:

它实现了AutoCloseable接口,可以使用try-with-resources自动关闭资源。

创建一个 Scanner 对象:

1
Scanner s = new Scanner(System.in);

接收 String 类型输入

  • next()
    • 一定要读取到有效字符后才可以结束输入。
    • 对输入有效字符之前遇到的空白,next()方法会自动将其去掉。
    • 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
    • next() 不能得到带有空格的字符串。
  • nextLine()
    • 以Enter为结束符,也就是说nextLine()方法返回的是输入回车之前的所有字符。
    • 可以获得空白

接收intlong类型的输入,可以使用nextInt()nextLong()等。但是有以下几点要注意的地方:

  1. 这类方法不会消耗回车键产生的换行符,但是nextLine()会读取换行符,所以在二者混用的时候要注意:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ScannerDemoTest {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);

System.out.print("请输入一个数字:");
int num = scan.nextInt(); // 输入:123

System.out.print("请输入一句话:");
String line = scan.nextLine(); // 问题出在这里

System.out.println("你输入的数字是:" + num);
System.out.println("你输入的话是:" + line);

scan.close();
}
}

控制台打印:

1
2
3
请输入一个数字:123
请输入一句话:你输入的数字是:123
你输入的话是:

解释:输入123,按下回车键的时候,123赋值给了num,与此同时line接收到回车符,因此还没来得及输入一句话程序就结束了。

解决方法:在int num = scan.nextInt();后面紧跟一个scan.nextLine(),把回车吸收掉。

  1. nextInt()等接收特定数据类型不能接收其他类型的数据,否则运行时会报异常Exception in thread "main" java.util.InputMismatchException,所以在接收数据之前最好使用hasNextInt()判断输入的数据是否符合要求。
  2. nextIntnext()等都可以把空格作为分隔符,这样方便我们在一行内输入一个数组,比如对于下面这种输入格式
1
2
3
4
3
1 4 5 -1
1 3 4 -1
2 6 -1

利用nextInt()和适当的条件判断就能搞定。

测试类的命名

使用单元测试JUnit时,如果测试类的命名不规范,那么IDEA会报警告:

1
Test class name 'methodTest' doesn't match regex '[A-Z][A-Za-z\d]*Test(s|Case)?|Test[A-Z][A-Za-z\d]*|IT(.*)|(.*)IT(Case)?'

某些测试框架(如 Maven Surefire、JUnit、IDE 插件)会用正则表达式来自动识别哪些类是“测试类”。

上面这个正则表达式规定了测试类必须符合以下格式之一:

  • 以大写字母开头,并以 Test、Tests 或 TestCase 结尾,如:
    • LoginTest
    • CalculatorTests
    • NetworkTestCase
  • 或者 以 Test 开头,如:
    • TestLogin
    • TestConnectionManager
  • 或者包含 IT(通常代表集成测试):
    • UserServiceIT
    • ITLoginFlow

实用方法

split

定义:

1
2
3
public String[] split(String regex) {
return split(regex, 0, false);
}

作用:根据给定的正则表达式分割字符串。

  • 参数:定界正则表达式
  • 返回值:根据给定的正则表达式分割得到的String[]数组

举例:输入 IP 地址和子网掩码,输出网络地址和主机地址。第一步从给定的字符串中提取数字的过程可以用split完成:

1
2
3
4
5
6
7
8
private static int[] parse(String str) {
String[] newStr = str.split("\\.");
int[] result = new int[4];
for(int i = 0; i < 4; i++) {
result[i] = Integer.parseInt(newStr[i]);
}
return result;
}

运行以下单元测试:

1
2
3
4
5
6
7
@Test
public void test1() {
String s = "192.168.1.10";
int[] result = parse(s);
System.out.println(Arrays.toString(result));
// [192, 168, 1, 10]
}

可见原字符串中的小数点已经被成功去掉,四个数字被转换成整型变量保存在了数组中。

小数点属于正则表达式中的特殊字符,.用于匹配任意一个字符,想匹配它本身必须在前面加上\\。所以必须用"\\."来表示匹配小数点。类似的特殊字符还有:

字符 含义 匹配自身需写作
. 匹配任意单个字符(除换行) \\.
* 匹配前面的内容零次或多次 \\*
+ 匹配前面的内容一次或多次 \\+
? 匹配前面的内容零次或一次 \\?
^ 匹配字符串的开头 \\^
$ 匹配字符串的结尾 \\$
[ 开始一个字符类 \\[
] 结束一个字符类 \\]
{ 指定匹配次数(如 {3} \\{
} 结束指定次数 \\}
( 开始一个分组 \\(
) 结束一个分组 \\)
\| 逻辑“或” \\\|
\\ 转义符本身 \\\\

Java 查缺补漏
https://kznep19.blog/2025/05/08/Java后续问题补充/
作者
banyee
发布于
2025年5月8日
许可协议