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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • idea社区版支持jsp_idea没有servlet选项

    idea社区版支持jsp_idea没有servlet选项在几个javaIDE中,IntelliJIDEA应该是最养眼的了,不过免费的社区版不能配置web服务器,所以拿来开发servlet感觉困难重重。经过一番探索,终于闯出了一条便捷的路。快速编码,运行,调试都没问题,我所使用的版本是14.0.1。下面就来介绍一下。1、下载jetty。jetty是一个servlet容器,这一步是能够运行和调试的重点,因为不能配置web服务器,所以我们需要一个嵌入式的…

    2022年9月22日
    2
  • VBScript经典教程以及函数手册

    VBScript经典教程以及函数手册   Vbs经典教程:   https://www.jb51.net/article/53280.htm   Vbs函数手册:   https://www.jb51.net/shouce/vbs/

    2022年6月29日
    26
  • enumerateObjectsUsingBlock、enumerateObjectsWithOptions、enumerateObjectsAtIndexes、makeObjectsPerfor使用

    enumerateObjectsUsingBlock、enumerateObjectsWithOptions、enumerateObjectsAtIndexes、makeObjectsPerfor使用

    2022年1月1日
    65
  • Jmeter教程(一) – 入门

    Jmeter教程(一) – 入门一、下载登录官网Jmeter下载,得到压缩包jmeter-5.0.tgz,下载地址:http://jmeter.apache.org/download_jmeter.cgi。二、安装将下载得到的压缩包解压即可,这里我解压到自己电脑的路径为E:\Mysoftware\apache-jmeter-5.0。三、运行点击bin目录下的jmeter.bat即可启动Jmeter。启动后可以看到…

    2022年6月6日
    33
  • Pytest(13)命令行参数–tb的使用「建议收藏」

    Pytest(13)命令行参数–tb的使用「建议收藏」前言pytest使用命令行执行用例的时候,有些用例执行失败的时候,屏幕上会出现一大堆的报错内容,不方便快速查看是哪些用例失败。–tb=style参数可以设置报错的时候回溯打印内容,可以设置参

    2022年7月28日
    9
  • Ubuntu安装JDK教程

    Ubuntu安装JDK教程Ubuntu安装JDK教程jdk的下载和安装:1、打开浏览器,输入jdk的官网地址:https://www.oracle.com/java/technologies/javase-downloads.html,如图:2、找到需要下载的jdk版本,这里以1.8版为例,找到JavaSE8,点击JDKDownload,跳转到JavaSE8的下载页面,如图:3、找到对应的下载版本,我这里是Ubuntu64位的系统,需要找到linux64的jdk版本,点击进行下载,如图:4、下载成之后

    2022年7月12日
    17

发表回复

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

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