简体   繁体   English

在Java中按姓氏对学生数组进行姓氏排序

[英]Sorting an array of students by last name alphabetically in Java

I currently have this program read the contents of a text file and calculate the averages and amount of test scores taken and print them out neatly in a small data table. 我目前正在让该程序读取文本文件的内容,并计算所取考试成绩的平均值和数量,并将其整齐地打印在一个小的数据表中。 These are the names, amount of quizes taken and average of each student: 这些是姓名,测验数量和每个学生的平均成绩:

James Tiberius Kirk              8                         91.63 
Buffy Summers                    7                         83.14 
Tom Baker                       15                        100.00 
Malcolm Reynolds                 9                         84.22 
Elizabeth Bennet                 9                         93.33 
John Blutarsky                   9                          0.00 
Dorthy Gale                      6                         85.83 

All of these Student s are stored within the Array named Anames[] . 所有这些Student都存储在名为Anames[]的数组中。 I was wondering if it was at all possible to sort these students alphabetically by last name using the code that I have now. 我想知道是否有可能使用我现在的代码按姓氏字母顺序对这些学生进行排序 When I run the program it gives me the error: 当我运行程序时,它给了我错误:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1 线程“主”中的异常java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:-1

at java.lang.String.substring(String.java:1927)
at text.reader.TextReader.compareLastNames(TextReader.java:117)
at text.reader.TextReader.main(TextReader.java:94)

Here is the code of my main class: 这是我的主要课程的代码:

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

    Double score=0.0;
    int b,j;
    String tempfirst = "";
    String templast = "";
    Student Anames[] = new Student[30];
    Student Temp[] = new Student [1];
    int Stucount = 0;
    Scanner reader = new Scanner(new File("quizScores.txt"));
    boolean runProgram = true;
    PrintWriter writer = new PrintWriter(new File("scoreReport.txt"));
    //prints header for report
    System.out.println("Name                        Number Quizes             Quiz Socres");
    writer.println("Name                        Number Quizes             Quiz Socres");

    //check to see if end of file string
    while (!reader.hasNext("-10")){
        String name="", first="", last="";

        //gets the name from file
        while(!reader.hasNextDouble()){
            last = reader.next();

            while (!reader.hasNextDouble()){
                first = first+reader.next()+" ";
            }
            name=first+last;
        }

        //creates new student with given name
        Student newStudent = new Student(first, last);
        Anames[Stucount] = newStudent;
        Stucount++;

        //gets the quiz scores and makes sure does not averge in the end of file string.
        while (reader.hasNextDouble()&& !reader.hasNext("-10")){
           newStudent.addQuiz(reader.nextDouble());
        }

        //Prints out the formated data
        System.out.printf("%-30s%4.0f%30.2f \n",newStudent.getName(), newStudent.getQuizNumber(), newStudent.getAverage());
        writer.printf("%-30s%4.0f%30.2f",newStudent.getName(), newStudent.getQuizNumber(), newStudent.getAverage());

        writer.println();
    }
    System.out.println("\n");

    for (b = 0; b < Stucount; b++){
        int INTEGERTEMP = b;
        for (j= b+1; j < Stucount; j++){
            int INTEGERTEMP2 = j;
            if ((compareLastNames(Anames[INTEGERTEMP].getLAST(), Anames[INTEGERTEMP2].getLAST()))>0){
                Temp[0] = Anames[b];
                Anames[b] = Anames[j];
                Anames[j] = Temp[0];
            }
        }
    }

    System.out.println("Name                        Number Quizes             Quiz Socres");
    for (int i = 0; i < Stucount; i++) {

            System.out.printf("%-30s%4.0f%30.2f \n", Anames[i].getName(), Anames[i].getQuizNumber(), Anames[i].getAverage());

    }

    writer.close();
}

private static int compareLastNames(String a, String b){
    int index_a = a.lastIndexOf(" ");
    String surname_a = a.substring(index_a);
    int index_b = b.lastIndexOf(" ");
    String surname_b = b.substring(index_b);
    int lastNameCmp = surname_a.compareToIgnoreCase(surname_b);
    return lastNameCmp;
}

Here is the Student.java which contains most of the methods used: 这是Student.java,其中包含大多数使用的方法:

public Student (String inName, String inLast){
    studentName=inName;
    studentLast = inLast;
    quizAverage = 0;
    quizScore=0;
    numberQuizes=0;
}

public void addQuiz(double inQuiz){
    quizScore += inQuiz;
    numberQuizes++;
}

public double getAverage(){
    quizAverage = quizScore/numberQuizes;
    return quizAverage;
}

public String getName(){
    return studentName+studentLast;
}

public double getQuizNumber(){
    return numberQuizes;
}

public String getLAST(){
    return studentLast;
}

You can use java.util.Arrays.sort(Student [] arr, Comparator<Student> comp) instead of your own compare code. 您可以使用java.util.Arrays.sort(Student [] arr, Comparator<Student> comp)代替自己的比较代码。 In single line you can achieve it like this: 在单行中,您可以这样实现:

Student arr[];//considering this array you will populate
Arrays.sort(arr,new java.util.Comparator<Student>(){

            public int compare(Student o1, Student o2) {

                return o1.studentLast.compareTo(o2.studentLast);
            }

        });
//then the arr will be sorted with studentLast name

Let's work our way back from your exception to figure out where the problem is. 让我们努力摆脱异常,找出问题出在哪里。 First, it tells us we've got a StringIndexOutOfBoundsException on line 117; 首先,它告诉我们在第117行有一个StringIndexOutOfBoundsException that is, the line (it might actually be the surname_b line, you've removed code from the class that means I can't match up the lines properly) 也就是说,这一行(实际上可能是surname_b行,您已经从类中删除了代码,这意味着我无法正确匹配这些行)

String surname_a = a.substring(index_a);

You'll notice the message from the exception helpfully tells us that the index used was -1. 您会注意到来自异常的消息有助于告诉我们所使用的索引为-1。 Let's take a look at why a.lastIndexOf(" "); 让我们看一下为什么a.lastIndexOf(" "); would return -1. 将返回-1。 We see in the documentation for String that it returns -1 when the character does not occur in the String. 我们在String文档中看到,当String中没有出现该字符时,它返回-1。

Now, let's work another step back in the Exception's stack trace to figure out why there's no space in that String. 现在,让我们再往上一步,在Exception的堆栈跟踪中找出为什么该String中没有空格。 The Exception tells us to check line 94, where we see 异常告诉我们检查第94行,

if ((compareLastNames(Anames[INTEGERTEMP].getLAST(), Anames[INTEGERTEMP2].getLAST()))>0){

So, what's going on here? 那么,这是怎么回事? We're passing in the last names (and just the last names) from each of the students into our comparison function. 我们正在将每个学生的姓氏(也就是姓氏)传递到我们的比较函数中。 The last names, for the most part, have no spaces in them. 姓氏在大多数情况下都没有空格。

So, how do we fix this? 那么,我们该如何解决呢? Well, you'll have to change your function to only take substrings of the surname if there actually is a space in them, ie if the index returned isn't -1. 好吧,您必须将函数更改为仅在姓氏的子字符串中确实存在空格(即,如果返回的索引不是-1)时才接受姓氏的子字符串。

Once you've got the comparison function done, I recommend looking at how to write an Object that implements the Comparable interface . 完成比较功能后,建议您查看如何编写实现Comparable接口的Object This will allow you to use library sorting functions, which will be faster and less buggy than your own sorting functions (most likely!). 这将使您能够使用库排序功能,该功能比您自己的排序功能(最有可能的!)更快,且错误更少。

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

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