简体   繁体   中英

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. 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)

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. 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). 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. see the comments in the second while loop.

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 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.

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

Now use,

Collections.sort(List,comparator), to sort the List. 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.

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 . 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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