nextline函数_在JAVA中Scanner中的next()和nextLine()为什么不能一起使用?

nextline函数_在JAVA中Scanner中的next()和nextLine()为什么不能一起使用?Java输入一直是一个坑,本来一直用Scanner,但一直搞不懂换行符啥的,就用BufferReader,但前不久大疆笔试需要持续输入,早忘了Scanner怎么写,而那个场景用Scanner很好实现……就继续在这里记录一下Scanner的坑吧一、next&nextLine区别next不能得到带有空格的字符串一定要读到有效字符后才可以结束,结束条件是碰到空格…

大家好,又见面了,我是你们的朋友全栈君。

Java 输入一直是一个坑,本来一直用 Scanner,但一直搞不懂换行符啥的,就用 BufferReader ,但前不久大疆笔试需要持续输入,早忘了 Scanner 怎么写,而那个场景用 Scanner 很好实现 ……

就继续在这里记录一下 Scanner 的坑吧

一、next & nextLine

区别next不能得到带有空格的字符串

一定要读到有效字符后才可以结束,结束条件是碰到空格、tab 键、enter 键

nextLine可以获得空白

以回车作为结束符,也就是 nextLine 返回回车之前的所以字符

举例

代码调用分两种:

class ScannerDemo {

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

int num = sc.nextInt();

String[] str = new String[num];

for (int i = 0; i < num; i++) {

//str[i] = sc.next(); //str[i] = sc.nextLine(); }

sc.close();

}

}

1. next 使用举例:

输入 1:

2

abc

cba

结果 1:

str[0] = “abc”

str[1] = “cba”

原因:next() 方法在遇到有效字符前所遇到的空格、tab 键、enter 键都不能当作结束符。所以,读到 abc 后回车,存下第一个,读到 cba 后回车存下第二个。

输入 2:

2

abc cba

efg gfe

结果 2:

str[0] = “abc”

str[1] = “cba”

原因:next() 方法在遇到有效字符前所遇到的空格、tab 键、enter 键都不能当作结束符。所以,读到 abc 后有空格,存下第一个,读到 cba 后回车存下第二个。所以,循环退出。不是预期的 “abc cba” 和 “efg gfe”

2. nextLine 使用举例:

输入 1:

2

abc

cba

结果 1:

str[0] = “”

str[1] = “abc”

原因:以回车( “\r” )作为结束符,也就是 nextLine 返回回车( \r )之前的所以字符。

对于 “” 的情况分析:

在输入 2 的时候调用的是 nextInt返回:nextInt 返回的是结束符之前的内容,并不会返回结束符

我们的输入:2 \r

以回车 ( \r ) 结尾,于是 2 被返回,回车符 “\r” 它被丢弃在缓冲区中,现在缓冲区中,只有一个 \r ,于是 下一次 nextLine 扫描的时候就又扫描到了 \r,返回它之前的内容,也是啥都没有 “” ,然后再把 \r 去掉,

对于 “abc” 的情况分析:

下一次我们输入的是 abc\r,此时这个就是缓冲区的全部内容

所以下一次 nextLine 调用的时候,就返回 abc,再把 \r 去掉

输入 2:

2

abc bcf

efg gfe

结果 2:

str[0] = “”

str[1] = “abc bce”

对于 “” 的情况分析同输入 1

对于 “abc bce” 的情况分析:

第一次调用 nextLine 的时候,就清空了缓冲区,于是输入:abc bcf\r ,第二次调用 nextLine 的时候读取到了 \r 返回字符串 “abc bcf” 再把 \r 从缓冲区去掉

总结

总结一下,Scanner是一个扫描器,它扫描数据都是去内存中一块缓冲区中进行扫描并读入数据的,而我们在控制台中输入的数据也都是被先存入缓冲区中等待扫描器的扫描读取。这个扫描器在扫描过程中判断停止的依据就是“结束符”,空格,回车,tab 都算做是结束符

而坑点在于 next 系列的,也就是下面这些函数:next

nextInt

nextDouble

nextFloat

这些函数与 nextLine 连用都会有坑

坑点就是 next 系列的函数返回了数据后,会把回车符留在缓冲区,因此我们下一次使用 nextLine 的时候会碰到读取空字符串的情况

解决方案:输入都用 nextLine ,做格式转换

输入 next 系列函数调用后,中间调用一次 nextLine 调用去掉了回车符后,再调用一次 nextLine 调用真正输入我们的数据

都使用 nextLine:

class ScannerDemo {

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

int num = Integer.parseInt(sc.nextLine());

String[] str = new String[num];

for (int i = 0; i < num; i++) {

str[i] = sc.nextLine();

}

sc.close();

}

}

使用 next、nextLine 去临时回车符、nextLine 读入真正数据:

class ScannerDemo {

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

int num = sc.nextInt();

String[] str = new String[num];

sc.nextLine();

for (int i = 0; i < num; i++) {

str[i] = sc.nextLine();

}

sc.close();

}

}

这两种方式都能解决可读入带空格的字符串,并且不会读异常空串:

输入

2

abc cba

efg gfe

结果

str[0] = “abc cba”

str[1] = “efg gfe”

二、Scanner 性能

Scanner 是真的太慢了,一直用的是 BufferReader 写的,但今天一尝试就超时,于是改回用 BufferReader 就过了

归根结底是因为 Scanner 对输入字符实现了多样性的操作,BufferReader 就比较单一,读入的是字节流转换成字符串

实际测试,BufferReader 至少比 Scanner 输入快两倍

用 Scanner 是为了循环输入的功能,也就是 hasNext() 方法的功能

今天忽然想到了可以用死循环来代替,所以,还是继续使用 BufferReader 吧!少年!Scanner 性能劝退

class Main{

public static void main(String[] args) throws IOException {

BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));

while (true){

System.out.println(bf.readLine()); //循环输入 }

}

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/136846.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 最小生成树,克鲁斯卡尔算法入门。

    最小生成树,克鲁斯卡尔算法入门。

    2021年9月27日
    42
  • fork函数详解_全纯函数是什么

    fork函数详解_全纯函数是什么从最简单(基础)的一个例子说起,应该说是最基础而不是简单,下面的这个最基础的例子其实并不简单,因为有很多细节。我们需要从fork函数的定义开始说起:man手册官方定义thisfunctioncreatesanewprocess.Thereturnvalueisthezerointhechildandtheprocess-idnumberofthechildintheparent,or-1uponerror.这个函数创建一个新的进程。在子进

    2025年7月4日
    2
  • 保姆级-红米AC2100之breed不死后台刷写openwrt官方版&第三方改良版「建议收藏」

    保姆级-红米AC2100之breed不死后台刷写openwrt官方版&第三方改良版「建议收藏」刷机有风险!!!后果自负准备1.红米AC21002.基础的电脑操作breed不死后台第一步:环境准备进入小米路由器原始的管理页,miwifi.com或者192.168.31.1登录之后,检查固件版本第二步:降级这里必须降级,我们降到到2.0.7降级包地址链接提取码:tenk然后等几分钟连接上降级后的wifi,正常是redmi开头无密码连上后重新进入后台192.168.31.1自行设置向导,这里忽略然后检查一下系统版本是否降级成功第三步:写入breed此时注意浏览器

    2025年6月28日
    2
  • Apache Struts2再爆高危漏洞

    Apache Struts2再爆高危漏洞60网站安全检测最新struts2命令执行漏洞分析时间:2013-07-1809:46 在struts2中,DefaultActionMapper类支持以”action:”、”redirect:”、”redirectAction:”作为导航或是重定向前缀,但是这些前缀后面同时可以跟OGNL表达式,由于struts2没有对这些前缀做过滤,

    2022年7月13日
    12
  • js数组删除元素的方法_指甲都是小坑缺什么元素

    js数组删除元素的方法_指甲都是小坑缺什么元素JavaScript数组元素删除

    2022年9月30日
    2
  • ETAP软件–可靠性计算

    ETAP软件–可靠性计算对单辐射架空线路进行可靠性计算过程。图1单辐射架空线路分段接线图各元件可靠性参数如下:架空线路故障停运率(次/百公里) 55.865架空线路停电平均持续时间(小时) 4.1622断路器故障停运率(次/百台) 1.699断路器停电平均持续时间(小时) 4.8864开关故障停运率(次/百台) 54.677开关停电平均持续时间(小时) 1.9361每个负荷点带2个用户,架空线路长度,…

    2022年7月14日
    25

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号