【Java】Scanner 和 PrintStream的区别

有个问题,既然已经有了输入输出流,为啥还要有Scanner这个类呢?以下是参考了一下资料和自己的一些不成熟的理解

    Scanner:是一个可以使用正则表达式来分析基本类型和字符串的简单文本扫描器。比如遇到空格键,Tab键,Enter键。只要遇到其中之一,Scanner的方法就会返回下一个输入 。Scanner 使用分隔符模式将其输入分解为标记,默认情况下该分隔符模式与空白匹配。然后可以使用不同的 next 方法将得到的标记转换为不同类型的值。

    输入流:不管是字符流或者字节流,可以通过指定buffer,来对流数据进行读取,做个比喻你只是把桶子装满把数据装到程序里,而Scanner只不过对流进行了封装,然后提供了一些方便的方法而已,next或者nextline,Scanner是按照指定的标记来读数据,即使你桶子满了,但是没有遇到空格或者规定的标记,它会一直度,Scanner是基于正则表达是来扫描数据的
     换句话说:

     Scanner:基于正则表达读数据,或者基于某种条件读数据

     输入流:是基于“量”来度,可以一个一个,也可以桶子满了就读

     Scanner类似一个容器,将输入流放进去,然后通过nextXXX(),就可以通过特定的输入流中获取到数据,这个输入流不仅可以是控制台输入System.in,也可以是文件流

public class Test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int i = sc.nextInt();
        System.out.println(i);
    }
}
Scanner sc = new Scanner(new File("myNumbers"));
      while (sc.hasNextLong()) {
          long aLong = sc.nextLong();
      }

======================2018-8-29补充=====================

刷题的过程中无意发现几个关于Scanner的问题,阻塞了我很长时间,心态都快炸了:

有这样的代码:

		Solution test = new Solution();
		Scanner t = new Scanner(System.in);
	    t.useDelimiter(" ");
		while(t.hasNext()){
			System.out.println(t.next());
			test.Insert((Integer)t.nextInt());
			if(t.next().equals("exit"))//!!!!
				{
			    System.err.println("=======");
					break;
				}
		}

第一次用Scanner,有很多东西想当然了,我的目的是想命令行输入一行,回车结束,然后用空格分割我的输入,但是范了很多错:

1) nextInt和hasnextInt最好是成对使用,前后功能不一致,代码会显的很乱

2)每调用一次t.next,相当于是指针往后移了一位,next不仅仅会获取下一个元素的值,同时会把指针后移,因此应该先写一个局部变量存一下这个t.next。正常的写法:

while(t.hasNext())
{
    String e=t.next();
	System.out.println(e);		
	if(e.equals("exit"))//!!!!
	{
         System.err.println("=======");
	     break;
    }
}

3)本来像是使用  t.useDelimiter(" ") 定义用空格作为分隔符,用回车“\n”跳出while循环,但是事实上,这里有很多不是很方便的地方

 t.useDelimiter(" ");
while(t.hasNext())
{
    String e=t.next();
	System.out.println(e);		
	if(e.equals("\n"))//!!!!
	{
         System.err.println("=======");
	     break;
    }
}

 这样写实际上空格是跳不出这个循环的,其实这一点我还没有搞清楚,如果大神们知道,可以帮我解答一下,我个人的理解是\n回车在eclipse表示第一行dos已经输入完,输入回车,你就可以执行程序了,并且空字符字符串的最后一位是\n,所以会有很多冲突,因此用\n,程序是无法识别出来并推出的,但是如果你写成这样:比如你写1,2,3,exit,回车以后,循环就会推出,这里一定要要注意

  (a) 如果你1,2,3,回车再输入exit是退不出来的,因为逗号后面是回车+exit

  (b)如果你输入1,2,3,exit回车,也是退步出来的,因为逗号后面是,exit+回车

  (c)所以退出来的唯一方式就是,exit, 回车,程序开始读输入,逗号分隔前后用逗号分隔,会读出一个整个的exit,所以程序可以退

 t.useDelimiter(",");
while(t.hasNext())
{
    String e=t.next();
	System.out.println(e);		
	if(e.equals("exit"))//!!!!
	{
         System.err.println("=======");
	     break;
    }
}

 会发现这些写很不方便,后来我又试了一下,傻傻的想着回车来结束输入:

 t.useDelimiter(",");
while(t.hasNext())
{
    String e=t.next();
	System.out.println(e);		
	if(e.equals(""))//!!!!
	{
         System.err.println("=======");
	     break;
    }
}

事实上也是不行的,结束输入的是当前是空字符串的操作是:1,3,3,,  必须要用两个连续的逗号表示确实输入了一个空的字符串,显然也不是很方便,如果你非要用next和while来输入,可以这么写:

 t.useDelimiter("\n");
while(t.hasNext())
{
    String e=t.next();
	System.out.println(e);		
	if(e.equals("exit"))//!!!!
	{
         System.err.println("=======");
	     break;
    }
}

这样写就是,回车作为分割符,当你输入exit再回车,程序结束,这个是符合我的操作习惯的 

但是,我觉得你非要用空格+回车来分割和结束输入,可以用nextline,直接把一行读进来,然后在用split和trim来把字符串分割开,这样做的效果其实是很好的,代码如下:

		String e = null;
		if(test.hasNextLine()){
			e = test.nextLine();
		}
		String [] result = e.split(" ");
		for(int i =0;i<result.length;i++)
		System.out.println(result[i]);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值