1. 概述
在这个教程中,我们将学习如何使用Scanner
类的useDelimiter
方法。
2. java.util.Scanner
简介
Scanner
API提供了一个简单的文本扫描器。默认情况下,Scanner
会将输入分割成令牌,使用空格作为分隔符。让我们编写一个函数,它将:
- 将输入传递给
Scanner
- 遍历
Scanner
,将令牌收集到一个列表中
让我们看看基本实现:
public static List<String> baseScanner(String input) {
try (Scanner scan = new Scanner(input)) {
List<String> result = new ArrayList<String>();
scan.forEachRemaining(result::add);
return result;
}
}
请注意,在这段代码中,我们使用了try-with-resources
来创建Scanner
。这是因为Scanner
类实现了AutoCloseable
接口,这使得自动关闭资源成为可能。在Java 7之前,我们不能使用try-with-resources
,因此需要手动处理。
我们还可以注意到,为了遍历Scanner
元素,我们使用了forEachRemaining
方法。这个方法是Java 8引入的。Scanner
实现了Iterator
,如果我们使用较旧的Java版本,就需要利用这个特性来遍历元素。
正如我们所说,Scanner
默认使用空格解析输入。例如,调用baseScanner
方法,输入为"Welcome to Baeldung",应该返回包含以下有序元素的列表:"Welcome", "to", "Baeldung"。
让我们编写一个测试来检查我们的方法是否按预期工作:
@Test
void whenBaseScanner_ThenWhitespacesAreUsedAsDelimiters() {
assertEquals(List.of("Welcome", "to", "Baeldung"), baseScanner("Welcome to Baeldung"));
}
3. 使用自定义分隔符
现在,让我们设置Scanner
使用自定义分隔符。我们将传递一个字符串,Scanner
将使用它来拆分输入。
让我们看看如何做到这一点:
public static List<String> scannerWithDelimiter(String input, String delimiter) {
try (Scanner scan = new Scanner(input)) {
scan.useDelimiter(delimiter);
List<String> result = new ArrayList<String>();
scan.forEachRemaining(result::add);
return result;
}
}
让我们讨论一些示例:
- 我们可以使用单个字符作为分隔符:如果需要,字符需要转义。例如,如果我们想模仿基础行为,使用空格作为分隔符,我们将使用"\s"
- 我们可以使用任何单词/短语作为分隔符
- 我们可以使用多个可能的字符作为分隔符:为此,我们需要用
|
将它们分开。例如,如果我们想要在每个空格和换行符之间分割输入,我们将使用分隔符:"\n|\s" - 总之,我们可以使用任何正则表达式作为分隔符:例如,"a+"是一个有效的分隔符
让我们看看如何测试第一个案例:
@Test
void givenSimpleCharacterDelimiter_whenScannerWithDelimiter_ThenInputIsCorrectlyParsed() {
assertEquals(List.of("Welcome", "to", "Baeldung"), scannerWithDelimiter("Welcome to Baeldung", "\\s"));
}
实际上,useDelimiter
方法会在幕后将输入转换为一个封装在Pattern
对象中的正则表达式。另一种选择是自己处理Pattern
的实例化。为此,我们需要使用重写的方法useDelimiter(Pattern pattern)
,如下面所示:
public static List<String> scannerWithDelimiterUsingPattern(String input, Pattern delimiter) {
try (Scanner scan = new Scanner(input)) {
scan.useDelimiter(delimiter);
List<String> result = new ArrayList<String>();
scan.forEachRemaining(result::add);
return result;
}
}
要实例化Pattern
,我们可以使用compile
方法,如下所示的测试:
@Test
void givenStringDelimiter_whenScannerWithDelimiterUsingPattern_ThenInputIsCorrectlyParsed() {
assertEquals(List.of("Welcome", "to", "Baeldung"), DelimiterDemo.scannerWithDelimiterUsingPattern("Welcome to Baeldung", Pattern.compile("\\s")));
}
4. 总结
在这篇文章中,我们展示了一些可以用来调用useDelimiter
函数的模式示例。我们注意到,默认情况下,Scanner
使用空格分隔符,并指出我们可以在那里使用任何类型的正则表达式。
如往常一样,完整的代码可在GitHub上找到。