2014-11-04 101 views
0

我的构造函数获取文本文件的文件名,并将其转换为小写的所有单词的ArrayList,没有标点符号或空格。这些规格以及构造函数的参数都是由我的家庭作业指定的,所以不要建议我改变它们。如何摆脱这些空串?

private ArrayList<String> list; 

public Tokenizer(String file) throws IOException { 
    list = new ArrayList<>(); 
    String thisLine; 
    BufferedReader br = new BufferedReader(new FileReader(file)); 

    while ((thisLine = br.readLine()) != null) 
     list.addAll(Arrays.asList(thisLine.replaceAll("\\p{Punct}+"," ").toLowerCase().split("\\s+"))); 
} 

我的问题是,有很多空的字符串出现。我试过在“split”中使用“-1”作为第二个参数,但它似乎没有做任何事情。

我的另一个问题是如果它效率低下做Arrays.asList,或者如果我应该只是创建一个迭代器,再加上如果你认为我做了其他任何错误。例如,是否有另一种方法来输入文件名到BufferedReader

感谢

编辑1:

下面是测试我使用的在线图书(它是一个文本文件,有没有与文本文件的问题)我在古登堡计划中。使用我个人创建的文本文件时,我也会得到类似的结果,所以不要认为它是文本文件本身的问题。

其实,我只是复制了我的整个代码,因为它很简单:

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.IOException; 
import java.util.*; 

public class Tokenizer { 
    private ArrayList<String> list; 

    public Tokenizer(String file) throws IOException { 
     list = new ArrayList<>(); 
     String thisLine; 
     BufferedReader br = new BufferedReader(new FileReader(file)); 

     while ((thisLine = br.readLine()) != null) 
      list.addAll(Arrays.asList(thisLine.replaceAll("\\p{Punct}+"," ").toLowerCase().trim().split("\\s+"))); 
    } 

    public ArrayList<String> wordList() { 
     return list; 
    } 

    public static void main(String[] args) throws IOException { 
     Tokenizer T = new Tokenizer("C:\\...\\1898amongmyb00loweuoft_djvu.txt"); 

     ArrayList<String> array = T.wordList(); 

     for(int i = 0; i < 20; i++) { 
      System.out.println(array.get(i)); 
     } 
    } 
} 

这里是我的输出:

i 
9 



digitized 
by 
the 
internet 
archive 

in 
2007 
with 
funding 
from 

microsoft 
corporation 

没有,那些空线都没有空格。他们是空的字符串。如在“”中。我希望我尽可能清楚。

由于它可能会导致混淆,没有那不是我用于文件的路径名称的实际参数。省略号(“...”)只是简写,所以我不必将我的电脑目录透露给互联网。

另外,是的,最后还有一个空的字符串,但这个网站的界面不会让我把它放在那里。

编辑2:

我总是忘记东西,这里是文本文件的前几行:

我9

通过互联网档案馆

于2007年,资金数字化的from

Microsoft Corporation

http://www.archive.org/details/1898amongmyb00loweuoft

James Ettsscll Lotocll。

完整的诗歌和作品。 Riverside Edition,n vols,皇冠8vo,镀金上衣,每款1.50美元;该集合, $ 1 6. 50.

1-4。文学散文(包括我的学习窗口,其中 我的书,炉边旅行); 5.政治散文; 6.文学 和政治地址; 7。最新的文学论文和广告 - 旧英国戏剧家; 8-1 1.诗歌。

PROSE WORKS。河滨版。与肖像。 7卷, 皇冠8vo,镀金顶部,$ 10.50。

POEMS。河滨版。与肖像。 4卷,皇冠 8vo,镀金顶部,6.00美元。

完整的艺术作品。剑桥版。 从不透明纸上的透明类型印刷,并吸引力 界限。用肖像和雕刻的标题页,以及一个 洛厄尔家的小插图,Elmwood。大冠8vo,$ 2.00。 家庭版。与肖像和插图。皇冠 8vo,$ 1.50。

内阁版。 i8

我想我现在看到了这个问题。空字符串对应于空行。

编辑3:

所以我最终回答了我自己的问题。我结束了这样做:

while ((thisLine = br.readLine()) != null) { 
     ArrayList<String> newList = new ArrayList(Arrays.asList(thisLine.replaceAll("\\p{Punct}+"," ").toLowerCase().split("\\s+"))); 
     while(newList.remove(""));  
     list.addAll(newList); 
    } 

我没有尝试使用if语句,但然后你比较分裂前的行。这可能会产生问题,因为拆分可能会产生一些空行,然后您会错过。因此,我列出了我要添加到主列表中的列表,但在添加之前,我只是通过它并删除了所有空字符串的实例。

我真的不知道这是否是最有效的做事方式......如果它不让我知道!

+2

空字符串在充满 '' 空白?你可以修剪(),如果长度为0,那么它是一个完全空的字符串。 – Compass 2014-11-04 18:39:34

+0

由空字符串,我的意思是“”。根据我的理解,这通常是空字符串的意思。一个没有内部的字符串。 Jeez,我不认为这会造成混淆。 – Hank 2014-11-05 15:00:54

+0

'thisLine.replaceAll(“\\ p {Punct} +”,“”)'这不会产生一个空字符串EVER,除非'thisLine'是一个空字符串。因此为什么要问这个问题。 – Compass 2014-11-05 15:02:59

回答

0

您的问题很可能是您的thisLine从文件读取的开头或结尾有空格。对于文本文档来说,这种行是非常常见的。因此,如果您在\s+上调用拆分,并且该行以空格结束,则最后一项将是空字符串。

为了解决这个问题,我建议在分割之前在你的字符串中添加一个trim。

使用你的代码将其更改为:

list.addAll(Arrays.asList(thisLine.replaceAll("\\p{Punct}+"," ").toLowerCase().trim().split("\\s+"))); 

试一下,看看它是否没有摆脱大多数,如果不是所有的空字符串的。另外,您应该考虑将此声明分解为多个操作,以便阅读。

+0

所以我尝试了这一点,但我仍然得到空的字符串。我不知道你是否认为这一点,但空的字符串出现在列表中间,而不是在结尾。为什么他们出现对我来说并不明显。 – Hank 2014-11-05 15:04:10

0

怎么样和更换while ((thisLine = br.readLine()) != null) list.addAll(Arrays.asList(thisLine.replaceAll("\\p{Punct}+"," ").toLowerCase().trim().split("\\s+")));

while ((thisLine = br.readLine()) != null) if (thisLine.length() > 0) list.addAll(Arrays.asList(thisLine.replaceAll("\\p{Punct}+", " ").toLowerCase().trim().split("\\s+")));

+0

我已经尝试了类似的东西。这样做的问题是可能从“分割”中获得空字符串,然后会被遗漏并添加到ArrayList中。 – Hank 2014-11-07 12:52:27

+0

如果是这种情况,一旦完成拆分,您将需要丢弃它们 – 2014-11-07 13:12:35