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


相关推荐

  • RDIFramework.NET ━ Web中打印的各种方案参考-欢迎补充

    RDIFramework.NET ━ Web中打印的各种方案参考-欢迎补充

    2021年9月3日
    52
  • java延迟加载 dbutils_Lettuce「建议收藏」

    java延迟加载 dbutils_Lettuce「建议收藏」[TOC]#简介Lettuce是一个可伸缩的线程安全的Redis客户端,支持同步、异步和响应式模式。多个线程可以共享一个连接实例,而不必担心多线程并发问题。它基于优秀nettyNIO框架构建,支持Redis的高级功能,如Sentinel,集群,流水线,自动重新连接和Redis数据模型。#redis单机情况目前,Lettuce官方发布的最新的版本为[5.0.4](http…

    2025年7月5日
    2
  • android 获取收到短信验证码,Android自动获取短信验证码

    android 获取收到短信验证码,Android自动获取短信验证码如此当有短信收到时就可以将短信内容写到SD卡中的文件里在另一个java类中写个读取文件内容的方法,并在写测试用例过程中,将得到的String按验证码的具体位置截取即可。publicStringread(Stringstr)throwsIOException{Filefile=newFile(str);FileInputStreamfis=newFileInputStream(fi…

    2022年7月25日
    9
  • java培训机构_南阳清大教育培训机构

    java培训机构_南阳清大教育培训机构正文谈到MYSQL的事物,相信大家对这几个概念都不会陌生:四大特性:ACID并发问题脏读不可重复读幻读隔离级别ReadUncommitted(读未提交)ReadCommitted(读提交)RepeatableRead(可重读)Serializable(可串行化)下面的思维导图可能更表达得清晰????MySQL的默认事物隔离级别是RR(RepeatableRead),可重复读级别是能够解决脏读、不可重复读的这两个事物并发问题的,但是幻读的问题仍

    2022年9月26日
    1
  • 面试 设计题_设计模式面试题及答案

    面试 设计题_设计模式面试题及答案文章目录设计模式什么是设计模式为什么要学习设计模式设计模式分类设计模式的六大原则开放封闭原则(OpenClosePrinciple)里氏代换原则(LiskovSubstitutionPrinciple)依赖倒转原则(DependenceInversionPrinciple)接口隔离原则(InterfaceSegregationPrinciple)迪米特法则(最少知道原则)(Deme…

    2022年9月13日
    2
  • ffmpeg的安装和使用教程_Anaconda安装ffmpeg

    ffmpeg的安装和使用教程_Anaconda安装ffmpeg一、ffmpeg的简介FFmpeg是一个自由软件,可以运行音频和视频多种格式的录影、转换、流功能,包含了libavcodec——这是一个用于多个项目中音频和视频的解码器库,以及libavformat——一个音频与视频格式转换库。主要参数-i——设置输入档名。-f——设置输出格式。-y——若输出文件已存在时则覆盖文件。-fs——超过指定的文件大小时则结束转换。-t——指定…

    2022年9月12日
    0

发表回复

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

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