Java - 比较列表

时间:2012-04-19 03:41:46

标签: java sorting optimization

我有一个用Java编写的程序,它读入的文件只是一个字符串列表到LinkedHashMap中。然后它需要一个由两列组成的第二个文件,并且对于每一行,查看右手术语是否与HashMap中的一个术语匹配。问题是它运行得很慢。

这是一个代码片段,它将第二个文件与HashMap术语进行比较:

String output = "";

infile = new File("2columns.txt");
        try {
            in = new BufferedReader(new FileReader(infile));
        } catch (FileNotFoundException e2) {
            System.out.println("2columns.txt" + " not found");
        }

        try {
            fw = new FileWriter("newfile.txt");

            out = new PrintWriter(fw);

            try {
                String str = in.readLine();

                while (str != null) {
                    StringTokenizer strtok = new StringTokenizer(str);

                    strtok.nextToken();
                    String strDest = strtok.nextToken();

                    System.out.println("Term = " + strDest);

                    //if (uniqList.contains(strDest)) {
                    if (uniqMap.get(strDest) != null) {
                        output += str + "\r\n";
                        System.out.println("Matched! Added: " + str);
                    }

                    str = in.readLine();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            out.print(output);

从最初的ArrayList切换到LinkedHashMap,我获得了性能提升,但它仍然需要很长时间。我该怎么做才能加快速度呢?

2 个答案:

答案 0 :(得分:4)

您的主要瓶颈可能是您正在为while循环的每次迭代重新创建StringTokenizer。将其移出循环可能会有很大帮助。通过在while循环外移动String定义可以获得较小的加速。

最大的加速可能来自使用StreamTokenizer。请参阅下面的示例。

哦,使用HashMap而不是LinkedHashMap,因为@Doug Ayers在上面的评论中说:)

并且@MДΓΓБДLL建议对代码进行分析。结帐Eclipse Profiling Example

    Reader r = new BufferedReader(new FileReader(infile));
StreamTokenizer strtok = new StreamTokenizer(r);
String strDest ="";
while (strtok.nextToken() != StreamTokenizer.TT_EOF) {
    strDest=strtok.sval; //strtok.toString() might be safer, but slower
    strtok.nextToken();

    System.out.println("Term = " + strtok.sval);

    //if (uniqList.contains(strDest)) {
    if (uniqMap.get(strtok.sval) != null) {
        output += str + "\r\n";
        System.out.println("Matched! Added: " + strDest +" "+ strtok.sval);
    }

    str = in.readLine();
}

最后一个想法是(并且我对这个问题没有信心)如果你最后一次完成,写入文件也可能会更快。即将所有比赛存储在某种缓冲区中,并在一次点击中进行写作。

答案 1 :(得分:2)

StringTokenizer是一个遗留类。建议的替换是字符串“split”方法。

有些部分可能会合并。一次尝试就可以有多次捕获。

使用HashMap而不是LinkedHashMap的建议是一个很好的建议。由于不需要维护列表结构,因此获取和放入smidgeon的性能更快。

“output”字符串应该是StringBuilder而不是String。这可能会有很大帮助。