2015-11-03 55 views
0

我目前有這個程序讀取文本文件的內容,並計算平均值和採取的測試分數量,並將它們整齊地打印在小數據表中。這些名字,取測驗的數量和平均每個學生的:用Java按字母順序排列學生數組

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 S的存儲命名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; 
} 
+0

看來你的程序會認爲姓氏是James,Buffy,Tom,Malcolm,Elizabeth,John和Dorthy。 (或者我可能會感到困惑,看起來你並沒有真正使用'last'和'first'變量來表示最後名字和第一個名字,但是這部分代碼很混亂。) – ajb

+1

爲什麼不使用a定製比較器?這樣你不需要創建自己的compareLastnames方法 – AbtPst

+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 
+0

謝謝湯姆。我試着將你的代碼輸入到我的主類中,我面臨的唯一問題是它告訴我它需要一個.class類時需要一個值嗎?我是否將它插入錯誤的區域? –

+0

@ J.Z你接受的實際例外是什麼? – ptierno

+0

@ptierno異常在線程「主」java.lang.RuntimeException:不可編譯的源代碼 - 錯誤的樹型: \t at text.reader.TevaReader.main(TextReader.java:88) –

0

讓我們從異常中找回問題,找出問題出在哪裏。首先,它告訴我們在117線上有StringIndexOutOfBoundsException;也就是說,行

String surname_a = a.substring(index_a); 

你會從異常通知消息(它實際上可能是surname_b行,你已經從意味着我不能匹配正確的行類中刪除代碼)有用地告訴我們使用的索引是-1。我們來看看爲什麼a.lastIndexOf(" ");會返回-1。我們在documentation for String中看到,當字符不在字符串中時,它返回-1。

現在,讓我們再回到異常的堆棧跟蹤中,找出爲什麼該字符串中沒有空格。異常告訴我們檢查94行,我們看到

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

那麼,這是怎麼回事?我們將每個學生的姓氏(以及姓氏)傳遞給我們的比較函數。姓氏的大部分都沒有空格。

那麼,我們該如何解決這個問題呢?那麼,如果實際上有一個空格,即你返回的索引不是-1,那麼你必須改變你的函數只接受姓氏的子字符串。

一旦你完成了比較功能,我建議你看看how to write an Object that implements the Comparable interface。這將允許您使用庫排序功能,這將比您自己的排序功能更快,更沒有問題(最有可能!)。