2014-09-06 85 views
0

我有這樣一種方法,它將讀取文本文件並寫入臨時文本文件(用於重寫),然後刪除舊文件。該函數讀取並排序然後重寫。如何在java中排序文件

我有這樣的方法:

public void sortFile() 
{ 
    String line; int count = 0; int min; 
    int j=0; 
    try 
    { 
     BufferedReader asd = new BufferedReader(new FileReader(list)); 
     while((line=asd.readLine()) != null) 
     { 
      count++; //count how many lines 
     } 
     Object temp,temp1,temp2,temp3; 
     String names[] = new String[count]; 
     Double timeInd[] = new Double[count]; 
     String scores[] = new String[count]; 
     String difficulty[] = new String[count]; 

     while((line=asd.readLine()) != null) 
     { 
      String var[] = line.split("-"); 
      names[j] = var[0]; 
      timeInd[j]=Double.parseDouble(var[1]); 
      scores[j] = var[2]; 
      difficulty[j] = var[3]; 
      j++; 
     } 
     asd.close(); 

     if(count!=1) 
     { 
      for(int i=0; i<count; i++) //Selection sort 
      { 
       min=i; 
       for(int a=1; a<count ; a++) 
       { 
        if(timeInd[a]<timeInd[min]) min=a; 
       } 
       //swap values; 
       temp=names[i]; 
       temp1=timeInd[i]; 
       temp2=scores[i]; 
       temp3=difficulty[i]; 
       //////// 
       names[i] = names[min]; 
       timeInd[i]= timeInd[min]; 
       scores[i] = scores[min]; 
       difficulty[i] = difficulty[min]; 
       ///////// 
       names[min] = (String) temp; 
       timeInd[min] = (Double) temp1; 
       scores[min] = (String) temp2; 
       difficulty[min] = (String) temp3; 

      } 
     } 
     //rewrite the new sorted values; 
     PrintWriter write = new PrintWriter(new FileWriter(tempo,true)); 
     for(int i=0;i<count;i++) 
     { 
      write.println(names[i]+"-"+timeInd[i]+"-"+scores[i]+"-"+difficulty[i]); 
     } 

     write.close(); 
     list.delete(); 
     tempo.renameTo(list); 
    }catch(Exception e){}; 

} 

我的文本文件具有內容:

myName-12.999-100-Easy 

我把它們分成4正如你可以在我的代碼檢查上方。第一個是名字,第二個是時間,第三個是得分,第四個是難度。現在我的問題是,我想按升序排列我的文件,我的基礎是這個排序的時間。誰擁有最快的時間將會成爲頂級球員。順便說一下,我使用了選擇排序。然而。如果我的文本文件只有一行值。像上面的例子內容:

myName-12.999-100-Easy 

新重寫文本文件將擁有:

null-null-null-null 

即使我與我的 如果(!計數= 1)

但如果被困它我有這樣的多個記錄:

hisName-14.542-100-Easy 
herName-1.432-100-Easy 

它不會產生null null null null,但我t會產生相同的結果。它還沒有排序。爲什麼?我不知道這背後的邏輯問題是什麼。我希望你能幫助我。乾杯。

回答

0

第一點,

您正在閱讀的內容完全一次,

while((line=asd.readLine()) != null) 
     { 
      count++; //count how many lines 
     } 

未復位流,但你不能真正使用它的BufferedReader類,因爲它只能重置回一定數量的字節(緩衝區大小)。如果你的文件比這個大,它將不起作用,你試着再次讀取文件。你將永遠無法做到。由於讀者已經到達文件的末尾。

while((line=asd.readLine()) != null) 
     { 
      count++; //added now ----> 1 
      String var[] = line.split("-"); 
      names[j] = var[0]; 
      timeInd[j]=Double.parseDouble(var[1]); 
      scores[j] = var[2]; 
      difficulty[j] = var[3]; 
      j++; 
     } 

因此,您可以在第二個while循環內添加計數。請參閱第二個while循環中的註釋。

二點,

不抑制異常:

catch(Exception e){}; 

固定上述兩個將幫助您調試代碼。

關於代碼審查,您可以對平滑運行進行以下更改。

創建class.structure代表一行寫着:

class Data implements Comparable 
{ 
    String name; 
    Double timeInd; 
    String score; 
    String difficulty; 
} 

當你迭代從文件中的每一行,創建一個數據對象,填充它的屬性。

一旦循環完成,您將有一個列表。

編寫一個比較器,它根據它們的timeid比較兩個Data對象。

http://www.tutorialspoint.com/java/java_using_comparator.htm

現在使用,

Collections.sort(名單時,比較器),對列表進行排序。迭代已排序的數據列表並將屬性寫入新文件,無論您希望的格式如何。

實現注意事項:此實現了穩定的,自適應的, 迭代歸併需要遠小於n LG更少(n)的比較 當輸入陣列部分地排序,同時提供一個傳統的歸併排序時的 性能輸入數組是隨機排列的 。

+0

哇。我會試試這個。謝謝 – Roch 2014-09-06 17:02:59

+0

我正在計算多少行,以便我可以給以下數組固定的值。如果BufferedReader不是那麼可取。我可以使用掃描儀閱讀嗎? – Roch 2014-09-06 17:07:45

+0

編號爲什麼要一次讀取文件兩次。仔細閱讀,BufferedReader reset()不是最好的。您應該使用緩衝讀取器來讀取字符流,但要高效地進行。這是我的觀點。 – BatScream 2014-09-06 17:13:07

0

從效率或代碼可維護性的角度來看,您的選擇排序並不是一個很好的方法。

做的最好的事情是閱讀String對象爲List<String>,然後在列表中使用Collections.sort,提供Comparator比較兩個的String S和決定基礎上,String內的時間他們的訂單。這意味着你需要編碼的部分是提取時間和比較兩次的位;其餘部分將全部由JDK處理(高效)。

+0

我在考慮Collections.sort,但是如果我將去Collections.sort(timeIndicator),唯一排序的部分是timeInd,但剩下的怎麼樣?名稱,分數和難度?你能給我一個簡單的線索嗎? – Roch 2014-09-06 17:04:10

+0

您需要創建一個「比較器」,其「比較」方法根據所有值按順序進行比較。 – 2014-09-06 17:07:54

+0

@ Roch-請參閱下面的答案。 – BatScream 2014-09-06 17:15:36