java如何有选择的输入多行文本

今天在做作业的时候碰到了一个问题:要用java做词频统计,但是这就犯难了,java如何有选择性的进行文件输入输出呢?

查阅文档可知,inputStream类和outputStream类是字节流输入输出,而reader 类和writer 类则是直接Unicode码输入输出,我为了图省事,我最后使用了FileReader类的read方法进行文件读取。FileReader类中的read方法可以逐字符读取,返回类型为int,其实就是0~255的char 类型,只要进行强制类型转换,就可以得到读入的字符,当遇到文件尾的时候,该方法返回-1。因为是char类型,所以如果遇到中文字符,比如句号,就会按照两个char处理。

接下来解决选择性输入的问题。思路很简单:

  1.如果现在所读取到的字符不是我们想要的,那么就一直向下读取,直到读取到我们想要的

  2.如果遇到了返回值为-1的情况,退出,表示文件读取完成(这一步一定要放在中间判断)

  3.如果现在读取的是我们想要的,就一直读取,直到出现我们不需要的,退出,等待下一次读取。

解释一下第二个为什么要在中间判断吧。

因为如果放在三个判断的第一个,那么如果文件以无用的字符结尾,则最后一个单词输出后还会多余输出一个换行,因为return了一个空的StringBuffer,而输出语句用的是println。

如果放在三个判断中的最后,那么如果文件以有用单词结尾,则最后一个单词无法输出,因为扫描到单词后紧接着就是read返回-1,此时就直接返回“字符串完成”,所以少最后一个单词

第一次解决的时候,因为判断1的位置和判断3混在了一起,所以出现了最后一个单词不能输出的情况。

  错误写法我也写下来吧,以免以后再错:

错误1——放在最前面:

private String read() throws IOException{
StringBuffer strBuf = new StringBuffer();
int t=fileReader.read();
if(t==-1) return "\\$";

错误2——放在最后:

 while(t!=-1&&isAlph((char)t)){
strBuf.append((char) t);
t=fileReader.read();
}
if(t==-1) return "\\$";
return strBuf.toString();
}

正确做法:(完全代码,并且简化了不需要的流程)

 private String read() throws IOException{
StringBuffer strBuf = new StringBuffer();
int t=fileReader.read();
if(t==-1) return "\\$";
while(t!=-1&&isAlph((char)t)){
strBuf.append((char) t);
t=fileReader.read();
}
return strBuf.toString();
}

因此,可以看到代码的细节也是不容忽视的,同一句话,不同位置,导致结果大相径庭。

======================================我是小清新的分割线=========================================

2016.5.8更新

嗯,好吧,我又来啦,这次的java之旅差不多就已经完成啦,现在让我们梳理一下这次学到的输入流的组合方式:

除了上文中逐个字符进行输入的方法之外,对于有些问题,正则表达式可能更加好用。

比如我们想逐行读取文本怎么办呢,我们会发现FileReader类中是没有这种方法的,因此我们需要把File类和其他输入流组合起来,自力更生。比如我们把File和Scanner类结合起来,熟悉控制台的小伙伴们一定很清楚,Scanner常用来进行控制台输入,并且Scanner可以一次读取一行,因此,我们就选它啦。

因此我么可以愉快地一次一行进行操作啦

定义如下:(in 和 out 分别是输入流和输出流)

public Tree_T_Display(File fin,File fout) throws IOException {
in = new Scanner(new FileInputStream(fin));
out = new FileWriter(fout);
}

这样read()函数就可以这样定义啦:

public String read()throws IOException{
if(in.hasNext()){
String s = in.nextLine();
s=s.replaceAll(" ", "");//去掉空格
return s;
}
return null;
}

这样一来,配合正则表达式,我们的代码量可以减少,并且在过滤数据方面也可以交给正则表达式去做。

另外,正则表达式也提一下吧,在java的正则表达式我自己用过的有两种调用方法,一种是String类中的split,matches方法,注意split方法中匹配上的字符不会出现在新的字符串中,而matches方法中的正则必须和字符串完全匹配,否则就返回false。

另外,正则中,+表示1~n个(n)不限制,*表示0~n个,和{1,}  {0,}分别等价。

^表示行开头,$表示行结尾,^在[]中表示“非”,取补集

举例如下

目标:匹配“单词”开头+“(”结尾的字符串:

 s.matches("^[a-zA-Z]+[^\\(]$")

匹配可能有特殊字符的单词,缩写等:

 s.matches("^[^ ]+$")

这里就用到了^在[]中的情况,一个[]是一个可匹配的类,上面第二行作用是匹配一个“以非空格开头并且以之为结尾的字符串”

pte String read() throws IOException{
StringBuffer strBuf = new StringBuffer();
int t=fileReader.read();
if(t==-) return "\\$";
while(t!=-&&isAlph((char)t)){
strBuf.append((char) t);
t=fileReader.read();
}
//保留最大单词长度,为格式化输出做准备
maxLen = maxLen < strBuf.length() ? strBuf.length() : maxLen;
return strBuf.toString();
}

如何用java有选择的输入多行文本的更多相关文章

  1. 简单编程:如何用java来打印出一个5行的三角形

  2. java基础 ----- 选择结构

    ---------    流程控制 ------     流程图 ------   基本的  if  选择结构 import java.util.Scanner; public class GetPr ...

  3. java后台对前端输入的特殊字符进行转义

    转自:http://www.cnblogs.com/yangzhilong/p/5667165.html java后台对前端输入的特殊字符进行转义 HTML: 常见的帮助类有2个:一个是spring的 ...

  4. 如何用Java编写一段代码引发内存泄露

    本文来自StackOverflow问答网站的一个热门讨论:如何用Java编写一段会发生内存泄露的代码. Q:刚才我参加了面试,面试官问我如何写出会发生内存泄露的Java代码.这个问题我一点思路都没有, ...

  5. Java Swing 如何添加输入文字并且可以滚动的文本框?( JTextArea ,JScrollPane的使用)

    准备: JTextArea 文本区,一个可以输入文字的文本框 常用方法: 1.setText(String t)设置文本区中显示的文本 2.getText() 获取文本区中显示的文本 JScrollP ...

  6. Java从控制台接受输入字符

    创建一个类,在该类的主方法中创建Scanner扫描起来封装System类的in输入流,然后提示用户输入身份证号码,并输入身份证号码的位数. 代码如下: import java.util.Scanner ...

  7. java基础-基本的输入与输出

    java基础-基本的输入与输出 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.基本的输出 基本的输出,System.out 就是系统的标准输出设备,默认为显示器. 1>. ...

  8. Spring进阶—如何用Java代码实现邮件发送(一)

    相关文章: <Spring进阶—如何用Java代码实现邮件发送(二)> 在一些项目里面如进销存系统,对一些库存不足发出预警提示消息,招聘网站注册用户验证email地址等都需要用到邮件发送技 ...

  9. C#中的ComboBox实现只能选择不能输入,且下拉框中有默认值。

    下拉框有DropDownStyle这一属性,把DropDownStyle类型选为DropDownList,则下拉框只能选择不能输入了.但是这时的下拉框是没有默认值的,即使在Text属性中输入默认值,也 ...

随机推荐

  1. Oracle 同环比排除分母0

    A 本期 B 同期(环期) 同比(环比) =  (A-B)/B DECODE(NVL(B,0),0,0,ROUND(((A-B)/B),4)), --环比 DECODE(NVL(B),0,0,ROUN ...

  2. 微信小程序base64编码解码以及utf-8解码

    function base64_encode (str) { // 编码,配合encodeURIComponent使用 var c1, c2, c3; var base64EncodeChars = ...

  3. init_connect基本用法

    服务器为每个连接的客户端执行的字符串.字符串由一个或多个SQL语句组成.要想指定多个语句,用分号间隔开.例如,每个客户端开始时默认启用autocommit模式.没有全局服务器变量可以规定autocom ...

  4. 入门级:GitHub和Git超超超详细使用教程!

    GitHub和Git入门 考虑到大家以前可能对版本控制工具和Linux命令行工具都不了解,我写了一个简单的博客来让大家学会入门使用方法. GitHub的简单使用 第一步 创建GitHub账号 1. 打 ...

  5. centos网络配置之桥接模式

    一:前沿 来这家公司好久了,都没有开始写博客,都是积累着,都没有去写,今天实在是天激动了,我的虚拟机在配置好了之后折腾了一天都没有折腾出来可以上网,今天来了继续折腾,然后我该ip,改连接方式,我擦,终 ...

  6. HDU 4334 Trouble (数组合并)

    Trouble Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  7. R的农场

    R的农场 题目描述 最近,R 终于获得了一片他梦寐以求的农场,但如此大的一片农场,想要做好防卫工作可不是一件容易的事.所以 R 购买了 N 个守卫,分别让他们站在一定的位置上(守卫不可移动,同一位置上 ...

  8. [bzoj1015][JSOI2008]星球大战——并查集+离线处理

    题解 给定一张图,支持删点和询问连通块个数 按操作顺序处理的话要在删除点的同时维护图的形态(即图具体的连边情况),这是几乎不可做的 我们发现,这道题可以先读入操作,把没删的点的边先连上,然后再倒序处理 ...

  9. 小白科普之JavaScript的DOM模型

    微信公众号“前端大全”推送了一篇名为“通俗易懂的来讲讲DOM”的文章,把javascript原生DOM相关内容讲解的很详细.仔细读了一遍,觉得整理总结的不错,对自己也很使用,所以把内容整理过来,并根据 ...

  10. python面向对象进阶(上)

    一 .isinstance(obj,cls)和issubclass(sub,super) (1)isinstance(obj,cls)检查对象obj是否是类 cls 的对象,返回True和Flase ...