简体   繁体   中英

Sorting a text file lines in java

I have a text file which contains students information and it has 5 columns: ID, FName, LName, Age, Grade. I want to sort the lines of file by student's grade but it does not work. Here's my method:

public static void sortAndShow() throws Exception {
        ArrayList <Student> list = new ArrayList<Student>();
        BufferedReader reader = new BufferedReader(new FileReader(originalFile));
        String str = reader.readLine();
        while (str != null) {
            String[] detailsSt = str.split(" ");
            int id = Integer.parseInt(detailsSt[0]);
            String name = detailsSt[1];
            String lastname = detailsSt[2];
            int age = Integer.parseInt(detailsSt[3]);
            int grade = Integer.parseInt(detailsSt[4]);
            list.add(new Student(id, name, lastname, age, grade));
            str = reader.readLine();
        }
        Collections.sort(list, new gradeCompare());

        PrintWriter writer = new PrintWriter(new FileWriter(sortedFile, false));
        for (Student st : students) {
            writer.write((st.getStNum() + " " + st.getFirstName() + " " + st.getLastName() + " " + st.getAge() + " " + st.getGrade() + "\n"));          
        }
        reader.close();
        writer.close();
    }

And my inner class which do the compare process:

static class gradeCompare implements Comparator<Student> {
        @Override
        public int compare(Student o1, Student o2) {
            return o2.getGrade() - o1.getGrade();
        }
    }

My text file before sorting:

101 Jeff King 18 12
102 Tim Woods 17 19

But after sorting it write the same content in the new file:

101 Jeff King 18 12
102 Tim Woods 17 19

I want to after sorting my text file be like (last column is grade):

102 Tim Woods 17 19
101 Jeff King 18 12

What is students ?
Code is sorting list , but writing from students !

Collections.sort(list, new gradeCompare());
...
for (Student st : students) {

In this case the Comparator works, but subtraction is not recommended - can easily overflow/underflow. Do as Johnny suggested, or use Integer.compare(int, int) ,... or, functional:
Collections.sort(list, Comparator.comparingInt(Student::getGrade).reverse())


The code I used (not well formatted, since tested in jshell ):

record Student(int id, String name, String lastName, int age, int grade) {}

class gradeCompare implements Comparator<Student> { 
  public int compare(Student o1, Student o2) { 
    return o2.grade() - o1.grade(); 
  } 
}

String inp = """
101 Jeff King 18 12
102 Tim Woods 17 19
""";

ArrayList <Student> list = new ArrayList<Student>();
var reader = new BufferedReader(new StringReader(inp));
String str = reader.readLine();
while (str != null) {
  String[] detailsSt = str.split(" ");
  int id = Integer.parseInt(detailsSt[0]);
  String name = detailsSt[1];
  String lastname = detailsSt[2];
  int age = Integer.parseInt(detailsSt[3]);
  int grade = Integer.parseInt(detailsSt[4]);
  list.add(new Student(id, name, lastname, age, grade));
  str = reader.readLine();
}
Collections.sort(list, new gradeCompare());

Output:

 jshell> list list ==> [Student[id=102, name=Tim, lastName=Woods, age=17, grade=19], Student[id=101, name=Jeff, lastName=King, age=18, grade=12]]

Your mistake is that you are writing the elements from another list

Change this code:

for (Student st : students) {
        writer.write((st.getStNum() + " " + st.getFirstName() + " " + st.getLastName() + " " + st.getAge() + " " + st.getGrade() + "\n"));          
    }

To

for (Student st : list) {
        writer.write((st.getStNum() + " " + st.getFirstName() + " " + st.getLastName() + " " + st.getAge() + " " + st.getGrade() + "\n"));          
    }

The problem is you are using a students list (I'm not sure what does that one) So you should use list variable, which is the list what you ordered in Collections.sort(list, new gradeCompare());

And inside compare method, you should swap the return expresion, instead of o2.getGrade() - o1.getGrade(); you have to use like this:

public int compare(Student o1, Student o2) {
        return o1.grade - o2.grade;
    }

The problem is with your compare(Student thisStudent, StudenthatStudent) method implementaion. Try this -

public int compare(Student o1, Student o2) {
        if (o2.getGrade() > o1.getGrade()) {
          return -1; //return 1 when the grade is lower
        } else if (o2.getGrade() < o1.getGrade()) {
          return 1; //return 1 when the grade is the higher
        } else return 0; //return 0 when the grade is the same
    }

Then use Collections.sort(studentsList, gradeCompare)

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