【基础语法】Java Scanner hasNext() 和 hasNextLine() 的区别
OJ在线编程常见输入输出练习中默认模板
import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextInt()) { // 注意 while 处理多个 caseint a = in.nextInt();int b = in.nextInt();System.out.println(a + b);}}
}
API源码解析
JDK 8
hasNext
功能:判断是否还有下一个值,通过检查缓冲区数据和标记(token)实现。
关键方法:
循环检查输入:使用一个
while循环来不断检查输入源是否关闭(sourceClosed变量)。在循环内部:
- 如果当前缓冲区中有可用的标记(通过
hasTokenInBuffer()方法检查),则通过revertState(true)恢复状态并返回true。- 如果没有可用的标记,则调用
readInput()方法从输入源中读取更多的输入到缓冲区中。处理循环结束后的状态:如果循环因为
sourceClosed为true而结束(即输入源已经关闭),则再次检查缓冲区中是否有可用的标记。
Note:有三种重载。
/*** Returns true if this scanner has another token in its input.* This method may block while waiting for input to scan.* The scanner does not advance past any input.** @return true if and only if this scanner has another token* @throws IllegalStateException if this scanner is closed* @see java.util.Iterator*/public boolean hasNext() {ensureOpen();saveState();while (!sourceClosed) { //sourceClosed 跟踪输入源是否已经关闭if (hasTokenInBuffer())return revertState(true);readInput();}boolean result = hasTokenInBuffer();return revertState(result);}/*** Returns true if the next complete token matches the specified pattern.* A complete token is prefixed and postfixed by input that matches* the delimiter pattern. This method may block while waiting for input.* The scanner does not advance past any input.** @param pattern the pattern to scan for* @return true if and only if this scanner has another token matching* the specified pattern* @throws IllegalStateException if this scanner is closed*/public boolean hasNext(Pattern pattern) {ensureOpen();if (pattern == null)throw new NullPointerException();hasNextPattern = null;saveState();while (true) {if (getCompleteTokenInBuffer(pattern) != null) {matchValid = true;cacheResult();return revertState(true);}if (needInput)readInput();elsereturn revertState(false);}}/*** Returns true if the next token matches the pattern constructed from the* specified string. The scanner does not advance past any input.** <p> An invocation of this method of the form <tt>hasNext(pattern)</tt>* behaves in exactly the same way as the invocation* <tt>hasNext(Pattern.compile(pattern))</tt>.** @param pattern a string specifying the pattern to scan* @return true if and only if this scanner has another token matching* the specified pattern* @throws IllegalStateException if this scanner is closed*/public boolean hasNext(String pattern) {return hasNext(patternCache.forName(pattern));}
hasNextLine
功能:判断是否还有下一行。利用正则表达式匹配来查找行分隔符,并根据查找结果决定是否返回true。
方法实现:
保存当前状态:通过
saveState()方法保存当前扫描器的状态,以便在方法结束时可以恢复到这个状态。这是为了确保方法调用前后扫描器的状态不变。查找下一行:使用
findWithinHorizon(linePattern(), 0)方法尝试在输入中查找符合行模式的字符串。这里linePattern()返回用于匹配行模式的正则表达式,0表示没有超时限制。处理匹配结果:
- 如果找到了匹配项(即
result不为null),则进一步处理:
- 通过
this.match()获取匹配结果(MatchResult)。- 提取出匹配到的行分隔符(
lineSep)。- 如果存在行分隔符,则从结果中去除行分隔符部分,并缓存处理后的结果。
- 如果不存在行分隔符,则直接缓存结果(此时可能是读取到了输入的末尾,但没有明确的行分隔符)。
- 如果没有找到匹配项,则不缓存任何结果。
恢复之前的状态:通过
revertState()方法恢复扫描器到调用saveState()时的状态。返回结果:如果找到了下一行的匹配项(即
result不为null),则返回true;否则返回false。
Note:只有一种类型的接口,无参。
/*** Returns true if there is another line in the input of this scanner.* This method may block while waiting for input. The scanner does not* advance past any input.** @return true if and only if this scanner has another line of input* @throws IllegalStateException if this scanner is closed*/public boolean hasNextLine() {saveState();String result = findWithinHorizon(linePattern(), 0);if (result != null) {MatchResult mr = this.match();String lineSep = mr.group(1);if (lineSep != null) {result = result.substring(0, result.length() -lineSep.length());cacheResult(result);} else {cacheResult();}}revertState();return (result != null);}
结论用法
采用 hasXxxx 判断时,后面读取输入也要使用匹配的 nextXxxx 。
比如先用 hasNextLine 对控制台输入判断时,那么后续需要使用 nextLine 来处理输入。
- hasNext
- hasNextXxxx 判断下一个xxx类型
- hasNextLine 判断是否有下一行
关于 token 说明
上面有提到判断场景的token标记,那么这是什么概念和实际作用呢?
下一个标记可以先粗略理解为下一个数据(但数据类型未知)。
在Java的
Scanner类中,术语“标记”(token)通常指的是输入流中可以被识别并作为一个单元处理的字符串或字符序列。Scanner类使用分隔符(如空格、制表符、换行符等)来区分不同的标记。例如,当你使用Scanner从控制台读取输入时,你可以通过空格、逗号或其他分隔符来分隔不同的标记。
Scanner 的使用案例
在Java输入控制台(即标准输入流,通常是键盘输入)中,Scanner类通过以下方式实现标记的识别:
1、创建Scanner对象:new并将其与标准输入流(System.in)关联起来。
Scanner scanner = new Scanner(System.in);
2、设置分隔符(可选):默认情况下,Scanner使用空白(空格、制表符、换行符等)作为分隔符。但是,你可以通过调用useDelimiter(String pattern)方法来设置自定义的分隔符。
例如:逗号分隔标记
scanner.useDelimiter(",");
注意:设置分隔符会影响Scanner识别标记的方式。
3、读取标记:一旦Scanner对象被创建并配置了分隔符,你就可以使用next()、nextInt()、nextDouble()等方法来读取下一个标记了。这些方法会返回输入流中下一个与指定类型匹配的标记。例如:
String token = scanner.next(); // 读取下一个标记作为字符串
int number = scanner.nextInt(); // 读取下一个标记并尝试将其解析为整数
4、检查是否有下一个标记:在读取标记之前,建议使用hasNext()或hasNextLine()方法先检查输入流中是否还有下一个标记或行。这些方法会返回一个布尔值,指示是否还有更多的输入可供读取。例如:
if (scanner.hasNext()) { String token = scanner.next(); // 处理标记
}
5、关闭Scanner对象:完成输入操作后,应该关闭Scanner对象以释放资源。可以通过调用close()方法来实现:(虽然大部分时间没关闭也不会像数据库那样报错)。
scanner.close();
相关文章:
【基础语法】Java Scanner hasNext() 和 hasNextLine() 的区别
OJ在线编程常见输入输出练习中默认模板 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.…...
react使用Fullcalendar 实战用法
使用步骤请参考:react使用Fullcalendar 卡片式的日历: 需求图: 卡片式的日历,其实我是推荐 antd的,我两个都写了一下都能实现。 antd 的代码: antd的我直接用的官网示例:antd 日历示例 i…...
优秀项目经理必知的10款项目管理软件推荐
本文精心为项目经理推荐30款国内外免费的项目管理软件,涵盖桌面应用与Web平台,其中不乏优秀的开源软件。这些工具旨在助力项目经理高效规划、跟踪与控制项目,无论是通过甘特图进行可视化管理,还是利用任务分配、团队协作等功能&am…...
植物神经紊乱不用怕,这些维生素来帮你!
你是否经常感到身体疲惫、情绪波动大、心悸、胸闷?这可能是植物神经紊乱在作祟。别担心,通过合理的维生素补充,可以有效缓解症状,提升生活质量。今天,我们就来聊聊植物神经紊乱患者应该补充哪些维生素。 🔍…...
NRF52832学习笔记(41)——添加串口库libuarte
一、背景 由于板子上不支持硬件流控,在使用 app_uart_fifo 库接收串口大数据时,频繁报 APP_UART_COMMUNICATION_ERROR 错误,多次重新初始化后,串口也不再产生中断了。查看官方论坛后决定使用串口异步库 libuarte。 二、简介 Li…...
Moore Perf System 1.1版本
Moore Perf System(一款性能分析工具) 提供可视化界面,在时间轴上按时间顺序显示 CPU 和 GPU 的事件、吞吐和性能指标,帮助开发人员方便、快速、准确的定位到系统级别的性能瓶颈,进而进行针对性分析和优化,…...
SpringBoot+Shirp的权限管理
目录 怎么实现动态菜单 1.html页面 2.获取动态菜单 Shiro权限刷新 1. 配置Shiro 2. 创建权限刷新服务 3. 调用权限刷新服务 注意事项 如何更新ShiroFilter初始权限 怎么实现动态菜单 1.html页面 <ul class"nav side-menu"><!--第一重循环…...
OpenCV图像基础
目录 显示窗口 创建空白图像 保存图片 图像裁剪 调整图片大小 图像绘制 绘制圆形 绘制矩形 绘制直线 绘制文本 中文乱码 控制鼠标 视频处理 显示窗口 cv2.namedWindow(winname, flagsNone) 创建一个命名窗口,以便在该窗口中显示图像或进行其他图形操作…...
基于MATLAB的图像拼接技术
实验名称:基于MATLAB的图像拼接技术实验目的:利用图像拼接技术得到超宽视角的图像,用来虚拟实际场景。实验原理: 基于相位相关的图像拼接技术是一种基于频域的方法,通过求得图像在频域上是相位相关特点来找到特征位置…...
ComfyUI 快速入门(环境搭建)
ComfyUI 是一个现代化、灵活的用户界面(UI)工具,专为 AI 模型和深度学习框架设计,能够快速实现可视化操作和定制化界面。在本教程中,我们将介绍如何在本地机器上快速搭建 ComfyUI 环境,帮助你开始使用这一工…...
将HTML项目上传至Gitee仓库(详细教程)
1.登录giett giett地址链接:Gitee - 基于 Git 的代码托管和研发协作平台 2.新建一个giett仓库 创建后得到远程仓库: 3、在本地项目文件夹右击鼠标点击 Open Git Bash Here 4、输入命令 命令:git init,这个目录变成git可以管理的仓库,会出…...
如何应对Oracle SQL语句的数据去重问题,应该考虑哪几个方面?
引言 在数据管理和数据库设计中,数据去重是一个重要的课题。随着信息技术的快速发展,数据的产生速度和数量都在急剧增加,如何有效地管理和维护这些数据成为了一个亟待解决的问题。 数据去重不仅可以减少存储空间的占用,还可以提高数据查询的效率,确保数据的准确性和一致…...
论负载均衡技术在Web系统中的应用论文
一、概要叙述软件项目及其主要工作 在2023年,我有幸参与了某公司电子商务平台的研发项目,担任系统架构设计师一职。该项目旨在构建一个高性能、高可用性的电子商务平台,以支撑公司日益增长的在线业务需求。作为系统架构设计的核心成员&#…...
NumPy 数据类型
1.常用 NumPy 基本类型 (1)bool_:布尔型数据类型(True 或者 False) (2)int_:默认的整数类型(类似C 语言long,int32 或 int64) (3&a…...
JavaScript——(4)
【DOM】 一、DOM基本概念 DOM(Document Object Model,文档对象模型)是 JavaScript 操作 HTML 文档的接口,使文档操作变得非常优雅、简便。 DOM 最大的特点就是将 HTML 文档表示为 “节点树”。 DOM 元素/节点:就是…...
每日一练 | DHCP Relay(DHCP 中继)
01 真题题目 DHCP Relay 又称为 DHCP 中继,下列关于 DHCP Relay 的说法正确的是(多选): A. DHCP 协议多采用广播报文,如果出现多个子网则无法穿越,所以需要 DHCP Relay 设备。 B. DHCP Relay 一定是一台交…...
`psdparse`:解锁Photoshop PSD文件的Python密钥
文章目录 psdparse:解锁Photoshop PSD文件的Python密钥背景:为何选择psdparse?psdparse是什么?如何安装psdparse?简单函数使用方法应用场景常见Bug及解决方案总结 psdparse:解锁Photoshop PSD文件的Python密…...
考研要求掌握的C语言程度(插入排序)
插入排序是啥类型的排序 插入类型的 插入排序经常用在啥类型场景下 用在有序序列下的基础上插入新数据 时间复杂度分析 如果是有序的基础下,最好的时间复杂度是O(n); 普通情况下是O(n^2) 插入排序的原理是啥&am…...
mybatis源码解析-sql执行流程
1 执行器的创建 1. SimpleExecutor 描述:最基本的执行器,每次查询都会创建新的语句对象,并且不会缓存任何结果。 特点: 每次查询都会创建新的 PreparedStatement 对象。 不支持一级缓存。 适用于简单的查询操作,不…...
Golang | Leetcode Golang题解之第538题把二叉搜索树转换为累加树
题目: 题解: func getSuccessor(node *TreeNode) *TreeNode {succ : node.Rightfor succ.Left ! nil && succ.Left ! node {succ succ.Left}return succ }func convertBST(root *TreeNode) *TreeNode {sum : 0node : rootfor node ! nil {if n…...
纯前端到底要不要学 Java
最近被问了好几次:纯前端有没有必要学 Java。这问题其实没有标准答案,得看你现在在做什么、后面想往哪走。如果你平时的工作就是调 RESTful 接口、拿数据渲染页面,后端全给你包好了,那 Java 不学完全没问题。把 React、Vue 这些前…...
ZS315Q Type-C转DP1.4带PD100w方案,边投屏边充电,告别接口焦虑
作为轻薄本、游戏本用户,外接DP显示器时你是不是也遇到过这样的痛点:想投屏到大屏工作娱乐,Type-C接口被视频线占了,充电口就得另占一个,本来接口就没几个,鼠标U盘全都排不上队;更烦人的是就算不…...
解决Keil MDK中RL-ARM许可证错误L9937E的方法
1. 问题现象与背景解析最近在维护一个基于Keil MDK的嵌入式老项目时,遇到了一个棘手的许可证错误。项目需要使用RL-ARM实时库(Real-Time Library),但编译时出现了以下错误提示:Error: L9937E: RL-ARM is not allowed w…...
Atomic Layout嵌套布局最佳实践:构建复杂UI系统的完整指南
Atomic Layout嵌套布局最佳实践:构建复杂UI系统的完整指南 【免费下载链接】atomic-layout Build declarative, responsive layouts in React using CSS Grid. 项目地址: https://gitcode.com/gh_mirrors/at/atomic-layout Atomic Layout是一个基于React的声…...
别再为单细胞数据批次效应发愁了!手把手教你用Harmony算法搞定整合分析
单细胞数据整合实战:用Harmony消除批次效应的完整指南当你在不同时间、不同实验室或使用不同平台获得多个单细胞RNA测序数据集时,最令人头疼的问题莫过于批次效应——这种技术性差异会掩盖真实的生物学信号。想象一下,你精心设计的实验因为数…...
从临床医疗说起:当一种科学理论走到边界的时候
我有一个同学,是搞肌肉医学的。他在临床中发现了一个现象:某种头昏,在内科的检查检验和治疗框架下,往往找不出头绪;但从肌肉学的角度看,它可能只是枕下肌群的劳损。松解之后,头昏可以得到有效而…...
专业级AI音频处理实战指南:OpenVINO插件让Audacity变身智能音频工作站 [特殊字符]
专业级AI音频处理实战指南:OpenVINO插件让Audacity变身智能音频工作站 🎵 【免费下载链接】openvino-plugins-ai-audacity A set of AI-enabled effects, generators, and analyzers for Audacity. 项目地址: https://gitcode.com/gh_mirrors/op/openv…...
NISQ时代量子机器学习实战:从变分量子电路到混合架构落地
1. 量子机器学习:从NISQ时代的现实挑战到工程实践如果你关注前沿科技,最近几年一定频繁听到“量子计算”和“机器学习”这两个词。当这两个看似在不同轨道上狂奔的领域开始交汇,就诞生了一个充满想象力又极具挑战的新方向——量子机器学习。我…...
TVA视觉智能体专栏(三):零基础看懂TVA智能体:不是大模型噱头,是工业落地刚需技术
摘要:很多新人误以为TVA是概念炒作,实则是智能制造柔性质检的核心解决方案。本文用通俗工程视角拆解TVA核心架构,详解Transformer注意力机制、DRL强化学习、FRA因式分解的协同逻辑,新手也能快速读懂智能体视觉底层逻辑。一、前言&…...
DeepSeek数据脱敏与联邦学习实战方案(2024最新版零信任架构白皮书)
更多请点击: https://intelliparadigm.com 第一章:DeepSeek数据隐私保护概述 DeepSeek系列大模型在训练与推理过程中严格遵循数据最小化、目的限定及用户可控原则,其隐私保护机制贯穿数据采集、预处理、模型训练、服务部署与日志管理全生命周…...
