首页 > Java > java教程 > 正文

Java Scanner.reset() 方法详解与应用场景

碧海醫心
发布: 2025-09-24 12:03:11
原创
543人浏览过

Java Scanner.reset() 方法详解与应用场景

Scanner.reset() 方法用于将 java.util.Scanner 实例的显式状态信息重置为默认值,主要影响由 useDelimiter()、useLocale() 或 useRadix() 更改的解析规则。在未修改这些状态时,调用 reset() 不会产生可见效果,但它在需要恢复默认解析行为时至关重要。java.util.Scanner 是 Java 中一个强大的文本扫描器,可以解析基本类型和字符串。它通过正则表达式来查找输入中的令牌,并可以使用多种方法来定制其解析行为。

Scanner.reset() 方法的核心作用

scanner.reset() 方法的主要目的是将 scanner 实例的显式状态信息恢复到其初始默认值。根据 oracle 官方文档的描述,当一个 scanner 被重置时,它会丢弃所有可能通过调用 usedelimiter(java.util.regex.pattern)、uselocale(java.util.locale) 或 useradix(int) 方法而改变的显式状态信息。

具体来说,reset() 方法会执行以下操作:

  • 重置分隔符模式: 如果使用 useDelimiter() 方法更改了分隔符,reset() 会将其恢复为默认的空白字符模式(p{javaWhitespace}+)。
  • 重置区域设置: 如果使用 useLocale() 方法更改了用于数字和日期解析的区域设置,reset() 会将其恢复为默认的系统区域设置。
  • 重置基数: 如果使用 useRadix() 方法更改了数字解析的基数(例如从十进制改为十六进制),reset() 会将其恢复为默认的十进制(基数10)。

需要注意的是,reset() 方法不会重置 Scanner 内部的缓冲区或底层输入流的读取位置。它只影响 Scanner 如何解释和解析后续输入。

何时 reset() 显得“无用”?

在文章开头提供的示例代码中,用户发现即使移除 s.reset(),程序也能正常运行。这正是因为在该示例代码中,Scanner 实例的 useDelimiter()、useLocale() 或 useRadix() 方法都没有被调用。换句话说,Scanner 的显式状态一直保持在默认值。在这种情况下,调用 reset() 实际上并没有任何状态可以“重置”,因此它不会对程序的行为产生任何可见影响。

例如,原始代码片段如下:

立即学习Java免费学习笔记(深入)”;

package com.company;

import java.io.IOException;
import java.util.Scanner;

public class Favorite_Number {
    public static void main(String[] args) throws IOException {
        int X,sum = 0,rem = 0,t;
        Scanner s = new Scanner(System.in);
        t = s.nextInt();
        while(t!=0) {
            s.reset();  // <-- 在这里移除它,程序仍然正常工作
            X = s.nextInt();
            while (X > 0) {
                rem = X % 10;
                if (rem == 5) {
                    sum++;
                }
                X = X / 10;
            }
            System.out.println(sum);
            sum = 0;
            t--;
        }
    }
}
登录后复制

由于 Scanner s 从未调用过 useDelimiter() 等方法来改变其解析状态,s.reset() 在这里是冗余的。

reset() 方法的实际应用示例

为了更好地理解 reset() 的作用,我们来看几个实际的例子。

AppMall应用商店
AppMall应用商店

AI应用商店,提供即时交付、按需付费的人工智能应用服务

AppMall应用商店 56
查看详情 AppMall应用商店

示例一:重置分隔符

默认情况下,Scanner 使用空白字符作为分隔符。我们可以通过 useDelimiter() 改变它,然后用 reset() 恢复。

import java.util.Scanner;

public class ScannerDelimiterResetExample {
    public static void main(String[] args) {
        String input = "Hello,World!Java-Programming";
        Scanner scanner = new Scanner(input);

        System.out.println("--- 默认分隔符(空白字符) ---");
        // 默认分隔符是空白字符,这里没有空白,所以整个字符串被视为一个token
        System.out.println("Next token: " + scanner.next()); // 输出: Hello,World!Java-Programming

        scanner.close(); // 关闭当前scanner

        scanner = new Scanner(input); // 重新创建一个Scanner

        System.out.println("
--- 使用逗号、感叹号或连字符作为分隔符 ---");
        scanner.useDelimiter("[,!\-]+"); // 设置分隔符为逗号、感叹号或连字符
        while (scanner.hasNext()) {
            System.out.println("Next token: " + scanner.next());
        }
        // 输出:
        // Next token: Hello
        // Next token: World
        // Next token: Java
        // Next token: Programming

        scanner.close(); // 关闭当前scanner

        scanner = new Scanner(input); // 重新创建一个Scanner

        System.out.println("
--- 先设置分隔符,再使用 reset() 恢复默认 ---");
        scanner.useDelimiter("[,!\-]+"); // 设置分隔符
        System.out.println("使用自定义分隔符获取第一个token: " + scanner.next()); // 输出: Hello

        scanner.reset(); // 重置Scanner状态,分隔符恢复为默认的空白字符
        System.out.println("重置后,使用默认分隔符获取下一个token: " + scanner.next()); // 输出: ,World!Java-Programming
        // 因为重置后分隔符变回空白字符,而剩下的字符串中没有空白字符,
        // 所以整个剩余部分被视为一个token。

        scanner.close();
    }
}
登录后复制

在这个例子中,可以看到 scanner.reset() 成功地将分隔符从自定义的 [,!\-]+ 恢复到了默认的空白字符,从而改变了后续 next() 方法的解析行为。

示例二:重置区域设置

Scanner 使用区域设置来解析数字和日期。例如,在某些区域设置中,小数分隔符是逗号而不是点。

import java.util.Locale;
import java.util.Scanner;

public class ScannerLocaleResetExample {
    public static void main(String[] args) {
        String input = "123.45 67,89";
        Scanner scanner = new Scanner(input);

        System.out.println("--- 默认区域设置(例如,en_US) ---");
        // 假设默认区域设置使用 '.' 作为小数分隔符
        System.out.println("Next double (default locale): " + scanner.nextDouble()); // 输出: 123.45

        scanner.close(); // 关闭当前scanner

        scanner = new Scanner(input); // 重新创建一个Scanner

        System.out.println("
--- 使用法国区域设置 (fr_FR) ---");
        scanner.useLocale(Locale.FRENCH); // 法国区域设置使用 ',' 作为小数分隔符
        System.out.println("Next double (French locale): " + scanner.nextDouble()); // 输出: 67.89
        // 注意:这里由于input是"123.45 67,89",
        // 默认Locale下,123.45是一个double,67,89则会解析失败或被视为两个token。
        // 而在French Locale下,123.45会被解析为整数123,而67,89会被解析为double 67.89。
        // 为了演示reset,我们简化一下输入。

        scanner.close(); // 关闭当前scanner

        String input2 = "123,45 67.89"; // 调整输入,以更好地演示
        scanner = new Scanner(input2);

        System.out.println("
--- 先设置区域设置,再使用 reset() 恢复默认 ---");
        scanner.useLocale(Locale.FRENCH); // 设置为法国区域设置
        System.out.println("使用法国区域设置获取第一个double: " + scanner.nextDouble()); // 输出: 123.45

        scanner.reset(); // 重置Scanner状态,区域设置恢复为默认
        // 假设默认区域设置为en_US,此时 '.' 是小数分隔符
        System.out.println("重置后,使用默认区域设置获取下一个double: " + scanner.nextDouble()); // 输出: 67.89

        scanner.close();
    }
}
登录后复制

这个例子展示了 reset() 如何将 Scanner 的区域设置从 Locale.FRENCH 恢复到系统默认区域设置,从而影响了 nextDouble() 方法对数字字符串的解析方式。

使用 reset() 的注意事项

  1. 不影响输入流位置: reset() 方法仅重置 Scanner 的解析状态,不会改变它从底层输入源(如 System.in、File 或 String)读取数据的位置。这意味着,如果 Scanner 已经读取了一些数据,reset() 不会“回溯”到输入流的开头。
  2. 不关闭 Scanner: 调用 reset() 不会关闭 Scanner。Scanner 仍然可以继续从其输入源读取数据。
  3. 主要用于恢复默认解析行为: reset() 最有用的场景是在 Scanner 的解析行为被 useDelimiter()、useLocale() 或 useRadix() 临时修改后,需要将其恢复到初始的默认行为时。
  4. 与 InputStream.reset() 的区别 不要混淆 Scanner.reset() 与 InputStream.reset()。后者是 InputStream 接口的一个方法,用于将输入流重置到上一个标记点(如果流支持并设置了标记),它确实会影响读取位置。两者功能完全不同。

总结

Scanner.reset() 方法是一个用于管理 java.util.Scanner 实例解析行为的重要工具。它允许开发者在修改了 Scanner 的分隔符、区域设置或基数后,方便地将其恢复到默认状态。在没有显式修改这些解析状态的情况下,调用 reset() 是冗余的,不会产生任何效果。理解其作用和适用场景,有助于编写更健壮、可预测的 Scanner 代码。

以上就是Java Scanner.reset() 方法详解与应用场景的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号