实现useDelimiter方法

时间:2012-05-09 11:39:02

标签: java

我有以下代码,请记住我刚开始学习一门语言,而且一直在寻找相当简单的练习。编码礼仪和评论家欢迎。

import java.util.*;
import java.io.*;

public class Tron
{
    public static void main(String[] args) throws Exception
    {
        int x,z,y = 0;
        File Tron= new File("C:\\Java\\wordtest.txt");
        Scanner word = new Scanner(Tron);
        HashMap<String, Integer> Collection = new HashMap<String, Integer>();
        //noticed that hasNextLine and hasNext both work.....why one over the other?
        while (word.hasNext())
        {
            String s = word.next();
            Collection.get(s);
            if (Collection.containsKey(s))
            {
                Integer n = Collection.get(s);
                n = n+1;
                Collection.put(s,n);
                //why does n++ and n+1 give you different results
            }else
            {
                Collection.put(s,1);
            }       
        }
        System.out.println(Collection);


    }   
}

不使用useDelimiter()我根据我的文件获得所需的输出:

Far = 2, ran = 4, Frog = 2, Far = 7, fast = 1, etc...

按如下方式插入useDelimiter方法

Scanner word = new Scanner(Bible);
word.useDelimiter("\\p{Punct} \\p{Space}");

提供以下输出,如下所示的文本文件中所示。

  

the the the

     青蛙蛙

     

     跑了跑跑

     

快速,快速

     

远,远,远远远

如果useDelimiter应该考虑标点符号新行等,为什么输出会产生这样的差异?可能很简单,但再次首先拍摄一个节目。提前感谢任何建议。

2 个答案:

答案 0 :(得分:2)

使用word.useDelimiter("\\p{Punct} \\p{Space}"),您实际上是在告诉扫描程序查找由标点符号后跟空格后跟另一个空白字符的分隔符。你可能想要这些中的一个(而且只有一个),这可以通过像

这样的东西来实现。
word.useDelimiter("\\p{Punct}|\\p{Space}");

至少一个,这看起来像

word.useDelimiter("[\\p{Punct}\\p{Space}]+");

更新

@Andrzej很好地回答了你的代码评论中的问题(我忘记了),但他错过了一个我希望扩展/放在这里的小细节。

  

为什么n ++和n + 1会给你不同的结果

这显然与行

有关
            n = n+1;

我的预感是你试过的替代方案是

            n = n++;

确实给出了令人困惑的结果(即最终结果是n 递增)。

原因是n++后缀增量运算符按其规范名称)递增n的值,但表达式的结果是原始值价值n所以正确使用它的方法就是

            n++;

其结果相当于n = n+1

以下是a thread with code example,希望能帮助您更好地了解这些运算符的工作原理。

答案 1 :(得分:0)

Péter对正则表达式是正确的,你匹配一个非常具体的序列而不是一类字符。

我可以回答您的来源评论中的问题:

  

注意到hasNextLine和hasNext都有效......为什么一个在另一个上面?

Scanner类被声明为实现Iterator<String>(因此它可以在任何需要提供字符串的任意事物的情况下使用)。因此,由于Iterator接口声明了hasNext方法,因此扫描程序需要使用完全相同的签名来实现此方法。另一方面,hasNextLine是Scanner自行实现的一种方法。

实现接口的类声明“通用命名”接口方法和更特定于域的方法并不完全不同寻常,这两种方法都做同样的事情。 (例如,您可能希望将游戏客户端实现为Iterator<GameCommand> - 在这种情况下,您拥有来声明hasNext,但可能希望拥有名为isGameUnfinished的方法,完全同样的事情。)

那就是说,这两种方法并不完全相同。如果扫描程序有另一个标记要返回,则hasNext返回true,而如果扫描程序有另一个输入行要返回,则hasNextLine返回true。 / p>

我希望如果您在不以换行符结尾的文件上运行扫描程序,并且只使用其中一个令牌,那么hasNext将返回truehasNextLine会返回false。 (如果文件以换行符结尾,则两种方法的行为相同 - 因为只有当并非所有行都被消耗时才会有更多的标记 - 但它们在技术上并非 一样。)

  

为什么n ++和n + 1会给你不同的结果

这非常简单。

n + 1只返回一个大于n当前值的值。而n++ 将n设置为更大,然后返回该值。

因此,如果n当前为4,则两个选项都返回 5;区别在于,如果您拨打nn + 1的值仍为4,但如果您拨打n++则为5。

通常,避免使用++运算符是明智的,除非在它用作样板文件的情况下(例如在for循环索引上)。拿两三个额外的字符,甚至是额外的字符来更清楚,更明确地表达你的意图是一个很小的代价,几乎总是值得做。