You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Scanner读int/double后nextLine()调用次数差异问题

现象原因说明

该差异和Java版本无关,核心是两个运行环境的输入流换行处理、输入提交逻辑不一致,Scanner本身的运行逻辑没有变化。

Scanner 基础读取逻辑

nextInt()、nextDouble()这类数值读取方法的固定逻辑是:

  • 启动读取时先跳过所有前置的默认分隔符(空格、制表符、\n、\r等空白字符)
  • 从第一个非分隔符开始读取对应类型的数值,碰到下一个分隔符就停止读取,不会消费停止位置的分隔符
  • nextLine()方法会从当前位置开始读取,直到碰到行分隔符为止,同时会消费掉这个行分隔符,返回分隔符之前的内容。

HackerRank 环境的输入特征

HackerRank的输入是预生成的标准文本流,严格遵循单换行分隔的格式,示例输入流结构如下:

[整数值][单个换行符][浮点数值][单个换行符][目标字符串]

这种结构下:

  1. nextInt()读取完整数后,停在整数后的第一个换行符位置,不消费该换行
  2. nextDouble()启动时跳过这个前置换行,读取完浮点数后,停在浮点数后的单个换行符位置,不消费该换行
  3. 第一次调用nextLine()刚好消费掉这一个残留换行,返回空串
  4. 第二次调用nextLine()即可正常读取目标字符串,也就是第一份代码可以正常运行的原因。

IntelliJ 环境的输入特征

IntelliJ控制台的输入是用户实时逐行提交的,和预生成文本流有明显差异:

  • Windows系统默认的行分隔符是\r\n两个字符,而非单个\n
  • 部分IntelliJ版本的控制台在逐行提交输入时,会在数值行末尾写入额外的分隔标记,导致浮点数读取完成后,缓冲区残留的不是单个换行标记,而是两个连续的分隔符片段

这种场景下:

  1. 第一次调用nextLine()只能消费第一个分隔符片段,返回空串
  2. 如果只调用一次nextLine()清理残留,后续读取字符串时会拿到空行,而非目标输入
  3. 多调用一次nextLine()才能把剩余的分隔符片段全部消费完,之后才能正确读取到目标字符串。

更稳妥的兼容写法

靠硬编码多次nextLine()适配特定环境的写法兼容性很差,通用方案是统一使用nextLine()读取整行内容,再手动做类型转换,从根源上避免分隔符残留问题,示例代码如下:

import java.util.Scanner;

public class Solution {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int i = Integer.parseInt(scan.nextLine());
        double d = Double.parseDouble(scan.nextLine());
        String s = scan.nextLine();
        scan.close();
        
        System.out.println("String: " + s);
        System.out.println("Double: " + d);
        System.out.println("Int: " + i);
    }
}

这种写法不依赖环境的换行符格式,在所有编译器、操作系统下都能稳定运行。

内容的提问来源于stack exchange,提问作者Naman Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 20:31:03