【Java学习笔记】Scanner类中next系列方法的总结
之前在学习Java的时候在如何通过键盘输入数据方面遇到了一些困难,当时有很多概念不理解,现在我把当时在网上看过的一些文章思路总结一下,其中可能有我个人的一些错误理解,希望大佬们指正,毕竟我还是个菜鸡/(ㄒoㄒ)/~~
这里就用最典型的三个方法来进行讲解
- next()
- nextInt()
- nextLine()
next系列的方法,他们的作用都是从键盘中接收数据。当程序执行到他们的时候,在命令行中就开始等待键盘输入了,而且要注意的是,这一系列方法的结束标志都是’\n’ 也就是回车(只有回车是终止标志,tab不是),他们从键盘中接收输入的内容,都是读到回车之后结束方法的调用。这几个方法都是不会读入最后的那个回车\n的。
一,next()方法
next()不光是在接收键盘输入的内容,而且还是在进行扫描分割。比如next()默认的分隔符时空格。
while (true) {
String n = cin.next();
System.out.println(n+'A');
}
那么我输入:grehre fsgeg hdrh
整个执行过程是这样的:
程序第一次执行到next()则开始从键盘输入,它会一直接收从键盘中打入的内容直到读取到回车,此回车并不会被读取
从键盘中输入的内容就放入了缓存区,这里我们再引入一个光标(cursor)的概念,在汇编中我们学过电脑就是通过光标一点点读取内容的。光标指向哪里,就读哪一个字符
当从键盘中输入完内容之后,next()方法开始对输入进来的内容进行扫描分割,光标从输入的内容最开始开始向后扫描,就是光标一点点地向后移动。当光标扫描到第一个分隔符(默认是空格)停止扫描,会创建一个String类的对象,里面存储的就是扫描的内容(不包含空格分隔符)返回创建的String对象的引用给n
然后输出了n字符串
但是要注意,当前光标还在之前键盘输入内容的行中,光标后面还有内容没有读取,所以当循环又执行到了next()方法后,计算机是不会再从键盘中读取数据的,因为当前光标还指向着字符。所以当再次到next()方法后,会继续从光标的位置扫描,但是后面全都是空格,next()如果没有扫描读入非空格或非回车字符是不会创建String对象并返回的。所以光标会继续向后扫描,并不会结束next调用向下执行输出,然后当扫描到第一个非空格字符,过程和之前就一样了
后面就都一样了,当光标已经扫完了所有的字符后,就会读取输出最后一个字符之后,当前光标的位置就又是空了,然后再执行到next()方法时,就又可以从键盘中输入数据了
以下就是上面代码的执行结果:
二,nextLine()方法
nextLine():读取输入,包括单词之间的空格和除回车以外的所有符号(即。它读到行尾)。读取输入后,nextLine()将光标定位在下一行。所以它和next()的区别就是它没有分隔符,直接扫描全部的键盘输入内容,并创建对象进行将其引用返回
三,nextInt()方法
nextInt() 是取next() 然后把字符串解析成一个int数字。
它本质是调用了next()方法,然后将next()方法返回的字符串再解析成int型数字返回。
hasNextInt() 是判断下次调用next()时否可以得到一个可以安全解析成int的字符串。下一个next()的返回值可以解析为一个数字,即符合数字的格式,那么返回true。注意当下一个字符串不能被解析成数字是,这个方法并不会返回false。
由上面的解释可以发现nextInt和next()是很像的,它也是有分隔符的概念,过程和next()都一样,只是它是把得到的字符串给解析成Int返回,而且只能是数字的字符串,即可以解析成数字的字符串才能调用成功,否则会有异常。如下代码:
while (true) {
int n = cin.nextInt();
System.out.println(n+"A");
}
以下是代码的运行效果:
nextInt方法的使用注意点(回车下坠)
以下参考:https://www.cnblogs.com/yoyotl/p/7457711.html
一、先看一段正常的代码
-
一段用Scanner捕获键盘输入的代码:
Scanner sc = new Scanner(System.in);
// 先读取键盘输入的字符串
System.out.println(“input name :”);
String name = sc.nextLine();
// 后读取键盘输入的int值
System.out.println(“input id :”);
int id = sc.nextInt();
System.out.println(“id = " + id + " name =[” + name + “]”);
System.out.println(“execute finish !”); -
测试结果
运行程序
input name :
lings //键盘输入
input id :
0 //键盘输入
程序输出
id = 0 name =[lings]
execute finish !
和预期一样。
二、一个小变化,颠倒一下取值类型的顺序
-
一段改变了取值顺序的代码:
Scanner sc = new Scanner(System.in);
// 先读取键盘输入的int值
System.out.println(“input id :”);
int id = sc.nextInt();
// 后读取键盘输入的字符串
System.out.println(“input name :”);
String name = sc.nextLine();
System.out.println(“id = " + id + " name =[” + name + “]”);
System.out.println(“execute finish !”); -
测试结果
运行程序
input id :
0 //键盘输入
input name :
程序输出
id = 0 name =[]
execute finish !
咦?说好的阻塞呢?我还没输入字符串怎么就执行结束了???
原因如下:
nextInt方法根据分隔符(回车,空格等)只取出输入的流中分割的第一部分并解析成Int,然后把后面的字节传递下去。
所以,第二种情况键盘实际输入是“0+回车”,nextInt读出了“0”,并留下了“回车”,
接着netxLine读到了一个“回车”,这是字符串的结束判定符啊,所以读到的字符串就是空字符串“”。
- 有点晕?继续测试:
运行程序
input id :
0 lings //键盘输入
input name :
程序输出
id = 0 name =[ lings] //注意空格
execute finish !
这个过程就是输入了"0 lings"字符串,先执行nextInt他扫描这个字符串的0扫描进去,当读到空格分隔符就结束本次分割,把字符零解析成int0返回,然后又执行到下面呢nextLine,光标从空格开始扫描,nextLine方法不按空格分隔所以会直接读到最后的回车结束,将取得的字符串返回
next()方法是不用考虑会查下坠的问题的
Scanner sc = new Scanner(System.in);
// 先读取键盘输入的int值
System.out.println("input id :");
int id = sc.nextInt();
// 后读取键盘输入的字符串
System.out.println("input name :");
String name = sc.next();
System.out.println("id = " + id + " name =[" + name + "]");
System.out.println("execute finish !");
这里就是正常输入就行,不会出现回车下坠的情况,这是因为next在扫描的时候只有扫描的分隔符和回车之外的字符才会真正开始扫描取字符,所以当扫到数字后面的那个回车的时候它本身是不会扫描进去的,直到扫描到非分割符的字符才会进行真正的扫描,然后遇到回车才会结束
三、使用注意事项
需要从键盘输入多个参数,尽量把nextLine类型放前面,nextInt放后面,实在不行。
nextInt后面要跟一个nextLine方法“消化”掉那个多余的字符串。
-
消化掉多余字符串的例子
Scanner sc = new Scanner(System.in);
System.out.println(“input id :”);
int id = sc.nextInt();
sc.nextLine();
System.out.println(“input name :”);
String name = sc.nextLine();
System.out.println(“id = " + id + " name =[” + name + “]”);
System.out.println(“execute finish !”); -
测试结果
运行程序
input id :
0
input name :
lings
程序输出
id = 0 name =[lings]
execute finish !