Using the compareTo method with an array to sort s

2019-04-16 15:57发布

问题:

I need to use the comparable interfact and a compareTo method to sort a list of students alphabetically and then by test score. I'm struggling at getting this to work in my application.

The list of names needs to be read from a text file. I don't know how many names will be in the text file that my professor uses except that it will be less than 100. I am also supposed to display the average of the grades at the bottom as well as write a message next to any student that is 15 points below average. I have not really gotten to the writing message part as I am currently stuck on getting the names and scores to print and sort.

The text file should look something like this:

Steelman Andrea 95

Murach Joel 98

Lowe Doug 82

Murach Mike 93

This is what I have so far... if someone could give me a little direction I'd appreciate it. Thank you.

package chapt11;
import java.io.FileReader;  
import java.util.Arrays; 
importjava.util.Scanner;
public class CH11AS8App {

/**
 * @param args
 */
public static void main(String[] args) throws Exception {

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

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

    Student [] studentArray;

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

    int nStudent = 100;  //array size not set unit run time
    studentArray = new Student[nStudent];

    for (int i=0; i<nStudent; i++)
    {
    System.out.println();

        while (aScanner.hasNext()) {
            lastName = aScanner.next();
            firstName = aScanner.next();
            examScore = aScanner.nextInt();

            System.out.println("Student " + nStudent++ + " " + firstName
                    + " " + lastName + " " + +examScore);

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


    }
        double sum = 0.0;
        sum += examScore;
        average = sum/nStudent;

        Arrays.sort(studentArray);

        System.out.println();

        for (Student aStudent: studentArray)
        {
            System.out.println(aStudent);

            if (examScore<= (average-10))
            {
                System.out.println ("Score 10 points under average");
        }
        System.out.println("Student Average:" +average);

        }
}
}
public interface Comparable {
    int compareTo(Object o);
}

class Student implements Comparable {

    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(Object o) {
        Student s = (Student) o;

        if (s.lastName.equals(lastName)) {
            return firstName.compareToIgnoreCase(s.firstName);
        } else {
            return lastName.compareToIgnoreCase(s.lastName);
        }
    }

    public String toString() {
        return lastName + ", " + firstName + ": " + examScore;

    }

}

}

回答1:

Firstly, delete entirely your Comparable interface. Use Comparable from the JDK.

Change your code to this

public static class Student implements Comparable<Student> {

    // rest of class omitted

    @Override
    public int compareTo(Student s) {
        if (s.lastName.equals(lastName)) {
            return firstName.compareToIgnoreCase(s.firstName);
        }
        return lastName.compareToIgnoreCase(s.lastName);return
    }
}

Note also that there is no "else" after a conditional return, so I omitted that redundant part of the code



回答2:

  1. You must not declare Comparable interface by yourself. Simply use it.
  2. You must sum exam scores of students inside loop but count average, sort array outside the loop.


回答3:

There are few things that needs correction in your code:

  1. Your Student class is inner class so to create object of that class you need first object of outer class. You probably wanted nested class that objects can be created without outer object (just add static modifier to Student class)
  2. To sort array with Arrays.sort() object must implement java.lang.Comparable interface, not interface created by you.
  3. You can use generics with Comparable<T> so try implementing your Student class with implements Comparable<Student>{ this way your compareTo method will can like

    public int compareTo(Student s){//body 
    

    instead of:

    public int compareTo(Object o){ 
        Student s = (Student) o; 
    
  4. Since your array will contain nulls (its default value for not filled places) you need to prevent sorting comparator from invoking compareTo on null element. To do it use Arrays.sort(Object[] a, int fromIndex, int toIndex) version of sorting algorithm.

  5. Check again your logic while collecting informations from file. To make things easier don't do few things at once. First collect all data, then do statistics.

  6. Don't sort array every time you add new data to it, do it after you add all data.


回答4:

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CH11AS8App {

    public static void main(String[] args) throws Exception {

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

        List<Student> studentArray = new ArrayList<Student>();

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

        String line;

        FileReader reader = new FileReader("src//chapt11//ch11AS8data.txt");
        BufferedReader bufferedReader = new BufferedReader(reader);
        String[] split;

        while ((line = bufferedReader.readLine()) != null) {
            split = line.split("\\s+");
            lastName = split[0];
            firstName = split[1];
            examScore = Integer.valueOf(split[2]);

            studentArray.add(new Student(firstName, lastName, examScore));
            double sum = 0.0;
        }
        Collections.sort(studentArray);

        System.out.println();

        System.out.println("sorted:" + studentArray);

        for (Student aStudent : studentArray) {
            System.out.println(aStudent);

            if (examScore <= (average - 10)) {
                System.out.println("Score 10 points under average");
            }
            System.out.println("Student Average:" + average);

        }
    }

    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 (this.firstName.equalsIgnoreCase(s.firstName)) {
                if (this.lastName.equalsIgnoreCase(s.lastName)) {
                    return this.examScore - s.examScore;
                } else {
                    return this.lastName.compareTo(s.lastName);
                }
            } else {
                return this.firstName.compareTo(s.firstName);
            }


        }

        public String toString() {
            return lastName + ", " + firstName + ": " + examScore;

        }

    }
}