简体   繁体   English

如何在Java中按文件排序

[英]How to sort in a file by in java

I have this one method that will read the text file and write to a temporary text file (for rewriting) and then delete the old one. 我有一种方法,该方法将读取文本文件并写入一个临时文本文件(用于重写),然后删除旧的文件。 This function reads and then sorts and then rewrites. 该函数先读取,然后排序,然后重写。

I have this method: 我有这种方法:

public void sortFile()
{
    String line; int count = 0; int min;
    int j=0;
    try
    {
        BufferedReader asd = new BufferedReader(new FileReader(list));
        while((line=asd.readLine()) != null)
        {
            count++; //count how many lines
        }
        Object temp,temp1,temp2,temp3;
        String names[] = new String[count];
        Double timeInd[] = new Double[count];
        String scores[] = new String[count];
        String difficulty[] = new String[count];

        while((line=asd.readLine()) != null)
        {
            String var[] = line.split("-");
            names[j] = var[0];
            timeInd[j]=Double.parseDouble(var[1]);
            scores[j] = var[2];
            difficulty[j] = var[3];
            j++;
        }
        asd.close();

        if(count!=1)
        {
            for(int i=0; i<count; i++) //Selection sort
            {
                min=i;
                for(int a=1; a<count ; a++) 
                {
                    if(timeInd[a]<timeInd[min]) min=a;
                }
                //swap values;
                temp=names[i];
                temp1=timeInd[i];
                temp2=scores[i];
                temp3=difficulty[i];
                ////////
                names[i] = names[min];
                timeInd[i]= timeInd[min];
                scores[i] = scores[min];
                difficulty[i] = difficulty[min];
                /////////
                names[min] = (String) temp;
                timeInd[min] = (Double) temp1;
                scores[min] = (String) temp2;
                difficulty[min] = (String) temp3;

            }
        }
        //rewrite the new sorted values;
        PrintWriter write = new PrintWriter(new FileWriter(tempo,true));
        for(int i=0;i<count;i++)
        {
            write.println(names[i]+"-"+timeInd[i]+"-"+scores[i]+"-"+difficulty[i]);
        }

        write.close();
        list.delete();
        tempo.renameTo(list);
    }catch(Exception e){};

}

My text file has a content: 我的文本文件包含以下内容:

myName-12.999-100-Easy

I split them into 4. As you can review in my code above. 我将它们分为4。您可以在上面的代码中进行检查。 the first is the name, second is the time, the third is the score and the fourth is the difficulty. 第一个是名称,第二个是时间,第三个是分数,第四个是难度。 Now my problem is that I want to sort my file into Ascending Order, my basis for this sorting is the time. 现在我的问题是我想将文件按升序排序,这种排序的依据是时间。 Whoever has the fastest time will be on the top of course. 时间最快的人当然是最重要的。 I used Selection Sort by the way. 我顺便用了选择排序。 However. 然而。 If my textfile has only one row of values. 如果我的文本文件只有一行值。 like example content above: 类似于上面的示例内容:

myName-12.999-100-Easy 

the new rewritten text file will now have: 新的重写文本文件现在将具有:

null-null-null-null

Even though I trapped it with my if(count!=1) 即使我用if(count!= 1)捕获了它

But if i have multiple records like this one: 但是,如果我有多个这样的记录:

hisName-14.542-100-Easy
herName-1.432-100-Easy

It would not produce null-null-null-null, but it would produce the same. 它不会产生null-null-null-null,但是会产生相同的结果。 It's not still sorted. 还没有排序。 WHY? 为什么? I don't know what's the logical problem behind this. 我不知道这背后的逻辑问题是什么。 I hope you could help me out. 我希望你能帮助我。 Cheers. 干杯。

First point, 第一点,

You are reading the content fully once, 您已经阅读了一次完整的内容,

while((line=asd.readLine()) != null)
        {
            count++; //count how many lines
        }

Without resetting the stream, however you can't really use it on the BufferedReader, because it can only reset back a certain number of bytes (the buffer size). 如果不重置流,则不能真正在BufferedReader上使用它,因为它只能重置一定数量的字节(缓冲区大小)。 if your file is bigger than that, it won't work, you try to read the file again. 如果文件大于该文件,它将无法正常工作,请尝试再次读取该文件。 Which you will never be able to. 您将永远无法做到。 Since the reader has already reached the end of the file. 由于读者已经到达文件末尾。

while((line=asd.readLine()) != null)
        {
            count++; //added now  ----> 1
            String var[] = line.split("-");
            names[j] = var[0];
            timeInd[j]=Double.parseDouble(var[1]);
            scores[j] = var[2];
            difficulty[j] = var[3];
            j++;
        }

So you could add the counting inside the second while loop. 因此,您可以在第二个while循环内添加计数。 see the comments in the second while loop. 请参阅第二个while循环中的注释。

Second point, 第二点

Don't suppress the exception: 不要抑制异常:

catch(Exception e){};

Fixing the above two will help you debug your code. 解决以上两个问题将帮助您调试代码。

With respect to code review, you could make the below changes for a smooth run. 关于代码审查,您可以进行以下更改以使运行顺利。

create a class.structure to represent a single line read: 创建一个class.structure来表示一行:

class Data implements Comparable
{
   String name;
   Double timeInd;
   String score;
   String difficulty;
}

when you iterate each line from the file, create a Data Object and populate its attributes. 当您遍历文件中的每一行时,请创建一个数据对象并填充其属性。

Once the loop is done, you will have a List. 循环完成后,您将获得一个列表。

Write a comparator which compares two Data objects based on their timeid. 编写一个比较器,该比较器根据两个Data对象的时间ID对其进行比较。

http://www.tutorialspoint.com/java/java_using_comparator.htm http://www.tutorialspoint.com/java/java_using_comparator.htm

Now use, 现在使用

Collections.sort(List,comparator), to sort the List. Collections.sort(List,comparator),对列表进行排序。 Iterate the sorted data list and write the attributes to a new file, whatever format you wish. 迭代排序的数据列表,然后将属性写入所需的任何格式的新文件。

Implementation note: This implementation is a stable, adaptive, iterative mergesort that requires far fewer than n lg(n) comparisons when the input array is partially sorted, while offering the performance of a traditional mergesort when the input array is randomly ordered. 实施注意事项:此实现是一种稳定的,自适应的,迭代的归并排序,当对输入数组进行部分排序时,所需的比较少于n lg(n),而当对输入数组进行随机排序时,它提供了传统归并排序的性能。

Your selection sort is not a great way of doing it, either in terms of efficiency or in terms of code maintainability. 从效率或代码可维护性的角度来看,选择排序都不是一个好方法。

The best thing to do would be to read the String objects into a List<String> , then use Collections.sort on the list, providing a Comparator that compares two of the String s and decides their order based on the time within the String . 最好的办法是将String对象读到List<String> ,然后在列表上使用Collections.sort ,提供一个Comparator ,该Comparator比较两个String并根据String的时间确定它们的顺序。 That means that all you have to code up is the bit that extracts the time and compares two times; 这意味着您只需编写代码即可提取时间并进行两次比较。 the rest will all be handled (efficiently) by the JDK. 其余的将全部由JDK处理(有效)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM