2

I posted a question about this last night but am still struggling. I need to sort a list of students from a text file first by name (in this format last name, first name), and then by test scores. I won't know how many students will be in the text file, other than that there is less than 100. I have to use the compareTo method (which I think I did correctly) and an array (I don't think I'm using this correctly). I have been messing around with this for literally hours on end and I just don't seem to get it. The text book really doesn't seem to be helping me any. How can I get my app class to print sorted student names/grades?

Other spefications are to get the average of the scores and make a comment next to any score below average. Those, however, I can work on after I can get the sorting straightened out.

Here is my code...

 package CH11AS8App;

 import java.io.FileReader;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Scanner;


 public class kjkkkkkkkkkkk {

 public static void main( String[] args ) throws Exception {
    // TODO Auto-generated method stub

        Scanner aScanner = new Scanner(
                                 new FileReader("src//chapt11//ch11AS8data.txt"));



        int numOfStudents = 100;
        Student[] studentArray = new Student[numOfStudents];
        Scanner sc = null;

        int counter = 0;
        while (aScanner.hasNext()) {
            sc = new Scanner(aScanner.nextLine());
            String lastName = sc.next();
            String firstName = sc.next();
            int score = sc.nextInt();


            studentArray[counter++] = new Student(lastName, firstName, score);

            studentArray[counter] = new Student(lastName, firstName, score); 

            int average= 0;
            int sum = 0;
            sum += score; 
             if (counter < numOfStudents); 
            average = sum / counter;
            if (score <= (average - 10)) {
             System.out.println("Score 10 points under average");
            System.out.println("Student Average:" + average);
        }



            sc.close();


            // Display Welcome Message
            System.out.println("Welcome to the Student Scores Application.\n");

            //Sort Names
            Arrays.sort(studentArray,0,counter, new Comparator<Student>(){
                @Override
                public int compare(Student s1, Student s2) {
                    return s1.getLastName().compareTo(s2.getLastName());
                }
            });

            System.out.println();
            System.out.println("Student list by name:");
            System.out.println();
            for(int j = 0; j < counter; j++){  
                System.out.println(studentArray[j]);

            }

            //Sort Scores
            Arrays.sort(studentArray,0,counter, new Comparator<Student>(){
                @Override
                public int compare(Student s1, Student s2) {
                    return Integer.valueOf(s2.getScore()).
                                       compareTo(Integer.valueOf(s1.getScore()));
                }
            });


            System.out.println();
            System.out.println();
            System.out.println("Student list by score:");
            System.out.println();
            for(int j = 0; j < counter; j++){  
                System.out.println(studentArray[j]);

            }


            //Close Scanner
            aScanner.close();

}

static class Student implements Comparable<Student> {

    //Instance Variables
    private String firstName;
    private String lastName;
    private int score;

    //Getters & Setters
    public Student( String firstName, String lastName, int score ) {
        this.firstName = firstName;
        this.score = score;
        this.lastName = lastName;
    }
    public int getScore() {
        return score;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }


    //CompareTo Method
    @Override
    public int compareTo( Student s ) {

        if( !firstName.equalsIgnoreCase( s.firstName ) ) {

            return firstName.compareToIgnoreCase( s.firstName );
        }

        if( !lastName.equalsIgnoreCase( s.lastName ) ) {

            return lastName.compareToIgnoreCase( s.lastName );
        }
            return (new Integer(score)).compareTo((new Integer(s.score)));
    }
        @Override public String toString(){ return lastName + ", "+ firstName        +" : "+score; }


    }

 }
newB
  • 35
  • 2
  • 2
  • 7
  • This is a possible duplicate of [Using the compareTo method with an array to sort students by name and test score](http://stackoverflow.com/questions/13326972/using-the-compareto-method-with-an-array-to-sort-students-by-name-and-test-score). Are you sure that this is a *new* question, and not just a continuation of the previous question? – Hovercraft Full Of Eels Nov 12 '12 at 02:35
  • Shouldn't `counter` be declared outside the `while` loop? And am I blind or is `counter` never incremented? ... and why are we sorting the array each time we read a Student rather than once at the end? – John3136 Nov 12 '12 at 02:39
  • When counter is declared outside of the loop and I run the program I get a list of errors. I don't know what you mean by sorting the array each time a student is read? – newB Nov 12 '12 at 03:06

3 Answers3

4

Your mistake is in the last line of the compareTo() method:

change

return examScore = s.examScore;

to

return examScore - s.examScore;


You want to return a difference, not set your instance variable!

Bohemian
  • 412,405
  • 93
  • 575
  • 722
1

I think you should change your last line in compareTo as below:

    return (new Integer(examScore)).compareTo((new Integer(s.examScore));

or

    return Integer.valueOf(examScore).compareTo(Integer.valueOf(s.examScore));

This will compare the two values and return accordingly.

EDIT:

Some corrections in your program:

  1. Add a toString() method in your Student class as:

    @Override public String toString(){ return firstName + " "+ lastName +" : "+examScore; }

  2. Update the main() method in app as below:

    public static void main(String[] args) throws Exception {
    
        Scanner aScanner = new Scanner(
                               new FileReader("src//chapt11//ch11AS8data.txt"));
    
        System.out.println("Welcome to the Student Scores Application.\n");
    
        int nStudent = 100;
        Student[] studentArray = new Student[nStudent];
        Scanner lineScanner = null;
    
        int counter = 0;
        while (aScanner.hasNext()) {
            lineScanner = new Scanner(aScanner.nextLine());
            String lastName = lineScanner.next();
            String firstName = lineScanner.next();
            int examScore = lineScanner.nextInt();
            System.out.println("Student " + counter + " " + firstName + " "
                    + lastName + " " + +examScore);
    
            studentArray[counter++]=new Student(lastName, firstName, examScore);
            lineScanner.close();
        }
    
        for(int j = 0; j < counter; j++){  
            System.out.println(studentArray[j]);
        }
    
    
    
        //sort based on first name
        Arrays.sort(studentArray,0,counter, new Comparator<Student>(){
            @Override
            public int compare(Student s1, Student s2) {
                return s1.getFirstName().compareTo(s2.getFirstName());
            }
        });
        System.out.println("Students sorted by first name in ascending order");
        for(int j = 0; j < counter; j++){  
            System.out.println(studentArray[j]);
        }
    
        //sort based on score
        Arrays.sort(studentArray,0,counter, new Comparator<Student>(){
            @Override
            public int compare(Student s1, Student s2) {
                return Integer.valueOf(s1.getExamScore()).
                                   compareTo(Integer.valueOf(s2.getExamScore()));
            }
        });
        System.out.println("Students sorted by score in ascending order");
        for(int j = 0; j < counter; j++){  
            System.out.println(studentArray[j]);
        }
    
        //To compute the average:
        double sum = 0.0;
        for(int j = 0; j < counter; j++){  
            sum+=studentArray[j].getExamScore();
        }
        double average = (sum*1.0)/counter;
        System.out.println("Average Score = "+average );
    
    
        aScanner.close();
    }
    
Yogendra Singh
  • 33,927
  • 6
  • 63
  • 73
  • And will capture the edge cases nicely. 1+ – Hovercraft Full Of Eels Nov 12 '12 at 02:54
  • Thank you, for the advice. I still can't get the program to run correctly. When I run it I am getting this output: Welcome to the Student Scores Application. Student 0 Andrea Steelman 95 [LCH11AS8App.app$Student;@7ba65cf7 1Student 0 Joel Murach 92 [LCH11AS8App.app$Student;@ba0abea 1Student 0 Doug Lowe 82 [LCH11AS8App.appStudent;@6176959c 1Student 0 Mike Murach 93 [LCH11AS8App.app$Student;@305866c1 1 – newB Nov 12 '12 at 03:13
  • @newB: Give me few minutes. I will be back. – Yogendra Singh Nov 12 '12 at 03:16
  • @newB: I updated your program to correctly read the students, sort them and print them. Currently, its sorting in the ascending order. If you have any questions, let me know. – Yogendra Singh Nov 12 '12 at 04:06
  • Thank you so much. The only issue is that it isn't sorting alphabeticallly... I see it sorting by name but not by score.. This is my output... Welcome to the Student Scores Application. Steelman, Andrea : 95 Murach, Joel : 92 Lowe, Doug : 82 Murach, Mike : 93 Steelman, Andrea : 95 Lowe, Doug : 82 Murach, Joel : 92 Murach, Mike : 93 – newB Nov 12 '12 at 04:25
  • @newB: How do you want it to be sorted? As per your comparator method, its sorts using the first name first. If matching first names, then only sorts on last name and if last name is also same then only sort on score. – Yogendra Singh Nov 12 '12 at 04:27
  • Nevermind, I figured it out. I can't even begin to tell you how much I appreciate your time... – newB Nov 12 '12 at 04:36
  • @newB: Not a problem. Glad to know that you are all set and your program is working now. If you think this is helpful, don't forget to accept the answer. – Yogendra Singh Nov 12 '12 at 04:39
  • I'm so bad at this... I populated a larger list in the text file and it's not sorting my grade, just by name... I think it might have to do with my compareTo method... I will certainly accept this as an answer. – newB Nov 12 '12 at 04:51
  • @newB: I know. I explained your sorting method i.e. how is it working at present. Let me know, how do you want it to be. I will try to help. Do you want to sort on score instead of name or based on name and score combined or something else? – Yogendra Singh Nov 12 '12 at 04:57
  • Two seperate lists one after the other. First list printing by name and the second printing by score. – newB Nov 12 '12 at 05:04
  • @newB: You are looking for two sorting methods in the case, which can be done little differently. Hang on, I will update the answer in couple minutes. – Yogendra Singh Nov 12 '12 at 05:09
  • @newB: I updated the answer with two sorting methods(based on first name and based on score). Both the sorting is done in ascending order. Let me know, if that doesn't help. – Yogendra Singh Nov 12 '12 at 05:20
  • I'm back.. new question and last question. I'm sorry. Can't get the average to print... This is what I am trying... double average= 0; double sum = 0.0; sum += examScore; average = sum/nStudent; System.out.println(average); – newB Nov 12 '12 at 21:12
  • @newB Better post a new question or update this question with your updated sample code so that I can have closer loop. **I am not seeing any loop in the above code** and think that's the problem. – Yogendra Singh Nov 12 '12 at 21:14
  • There is no loop... I should use a while loop? Edited... – newB Nov 12 '12 at 21:28
  • @newB: I updated the answer. Please check. – Yogendra Singh Nov 12 '12 at 21:36
0

Since this is homework I'm not giving you the full answer ... But here's the general idea of what you should be working towards ...

import java.io.FileReader;
import java.util.Scanner;

public class App {

    public static void main( String[] args ) throws Exception {
        // TODO Auto-generated method stub

        Scanner aScanner = new Scanner( new FileReader( "src/scores.txt" ) );

        System.out.println( "Welcome to the Student Scores Application." );
        System.out.println();

        Student[] studentArray;

        String lastName;
        String firstName;
        int examScore = 0;
        double average = 0;

        int nStudent = 100;
        studentArray = new Student[nStudent];

        int counter = 0;

        while( aScanner.hasNext() ) {

            lastName = aScanner.next();
            firstName = aScanner.next();
            examScore = aScanner.nextInt();

            studentArray[counter] = new Student( lastName, firstName, examScore );

            System.out.println( "Student " + studentArray[counter].getFirstName() + " " +  studentArray[counter].getLastName() + "'s " + "Test Score is :" + studentArray[counter].getExamScore() );
            ++counter;
            if( counter >= nStudent ) {
                break;
            }
        }
    }

    static class Student implements Comparable<Student> {

        private String firstName;
        private String lastName;
        private int examScore;

        public Student( String firstName, String lastName, int examScore ) {
            this.firstName = firstName;
            this.examScore = examScore;
            this.lastName = lastName;
        }

        // Get & Set Methods
        public int getExamScore() {
            return examScore;
        }

        public String getFirstName() {
            return firstName;
        }

        public String getLastName() {
            return lastName;
        }

        @Override
        public int compareTo( Student s ) {

            if( !lastName.equalsIgnoreCase( s.lastName ) ) {

                return lastName.compareToIgnoreCase( s.lastName );
            }

            if( !firstName.equalsIgnoreCase( s.firstName ) ) {

                return firstName.compareToIgnoreCase( s.firstName );

            }

            return examScore - s.examScore;

        }

    }

}
Edward J Beckett
  • 5,061
  • 1
  • 41
  • 41