在Java

时间:2015-11-03 03:36:45

标签: java arrays sorting

我目前有这个程序读取文本文件的内容并计算所取得的测试分数的平均值和数量,并在一个小数据表中整齐地打印出来。这些是名字,所取得的数量以及每个学生的平均数:

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 

所有这些Student都存储在名为Anames[]的数组中。我想知道是否有可能使用我现在的代码按姓氏字母顺序排序这些学生。当我运行程序时,它给了我错误:

线程“main”中的异常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)

这是我主要课程的代码:

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;
}

这是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;
}

2 个答案:

答案 0 :(得分:1)

您可以使用java.util.Arrays.sort(Student [] arr, Comparator<Student> comp)代替您自己的比较代码。在单行中你可以这样实现:

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

答案 1 :(得分:0)

让我们从您的异常中恢复过来,找出问题所在。首先,它告诉我们第117行有一个StringIndexOutOfBoundsException;也就是说,该行(它实际上可能是surname_b行,你已经从类中删除了代码,这意味着我无法正确匹配行)

String surname_a = a.substring(index_a);

您会注意到来自异常的消息有助于告诉我们使用的索引是-1。我们来看看a.lastIndexOf(" ");返回-1的原因。我们在documentation for String中看到,当字符串中没有出现字符时,它返回-1。

现在,让我们在Exception的堆栈跟踪中再做一步,找出为什么该String中没有空格。 Exception告诉我们检查第94行,我们在哪里看到

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

那么,这里发生了什么?我们将每个学生的姓氏(以及姓氏)传递给我们的比较函数。在大多数情况下,姓氏中没有空格。

那么,我们该如何解决这个问题呢?好吧,你必须改变你的函数,只有在它们实际上有空格的情况下才能获取姓氏的子串,即如果返回的索引不是-1。

完成比较功能后,我建议您查看how to write an Object that implements the Comparable interface。这将允许您使用库排序功能,这将比您自己的排序功能更快,更少错误(最有可能!)。