2016-10-01 35 views
0
public class JavaApplication13 { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     // TODO code application logic here 
     BufferedReader br; 
     String strLine; 
     ArrayList<String> arr =new ArrayList<>(); 
     HashMap<Integer,ArrayList<String>> hm = new HashMap<>(); 
     try { 
      br = new BufferedReader(new FileReader("words.txt")); 
      while((strLine = br.readLine()) != null){ 
       arr.add(strLine); 
      } 
     } catch (FileNotFoundException e) { 
      System.err.println("Unable to find the file: fileName"); 
     } catch (IOException e) { 
      System.err.println("Unable to read the file: fileName"); 
     } 


     ArrayList<Integer> lengths = new ArrayList<>(); //List to keep lengths information 


     System.out.println("Total Words: "+arr.size()); //Total waords read from file 

     int i=0; 
     while(i<arr.size()) //this loop will itrate our all the words of text file that are now stored in words.txt 
     { 
      boolean already=false; 
      String s = arr.get(i); 
      //following for loop will check if that length is already in lengths list. 
      for(int x=0;x<lengths.size();x++) 
      { 
       if(s.length()==lengths.get(x)) 
        already=true; 
      } 
      //already = true means file is that we have an arrayist of the current string length in our map 
      if(already==true) 
      { 

       hm.get(s.length()).add(s); //adding that string according to its length in hm(hashmap) 
      } 
      else 
      { 
        hm.put(s.length(),new ArrayList<>()); //create a new element in hm and the adding the new length string 
        hm.get(s.length()).add(s); 
        lengths.add(s.length()); 

      } 

      i++; 
     } 
     //Now Print the whole map 
     for(int q=0;q<hm.size();q++) 
     { 
      System.out.println(hm.get(q)); 
     } 
    } 

} 

這種方法是正確的嗎?根據長度將文本文本從文本文件分組爲Arraylist

說明:

  1. 負載的所有單詞到ArrayList。
  2. 然後遍歷每個索引並檢查單詞的長度,將它添加到包含該長度的字符串的ArrayList,其中這些ArrayList映射到包含單詞長度的散列映射中。

回答

1

首先,您的代碼僅適用於包含一行字的文件,因爲您將整行處理爲單詞。爲了使你的代碼更普遍您必須通過它分裂單詞來處理每一行:

String[] words = strLine.split("\\s+") 

其次,你不需要任何的臨時數據結構。從文件中讀取行後,您可以將地圖添加到地圖中。 arrlengths列表在這裏實際上沒有用處,因爲它們不包含除臨時存儲之外的任何邏輯。您正在使用lengths列表只是爲了存儲已添加到hm地圖的長度。調用hm.containsKey(s.length())可以達到同樣的效果。

並在您的代碼的附加註釋:

for(int x=0;x<lengths.size();x++) { 
     if(s.length()==lengths.get(x)) 
      already=true; 
    } 

,當你有一個這樣的循環,當你只需要找到如果某些條件爲任何元素真正的你不需要繼續當循環條件已經找到。您應該在if語句中使用break關鍵字來終止循環塊,例如

for(int x=0;x<lengths.size();x++) { 
     if(s.length()==lengths.get(x)) 
      already=true; 
      break; // this will terminate the loop after setting the flag to true 
    } 

但正如我已經提到你根本不需要它。這僅僅是爲了教育目的。

+0

非常有幫助我將做出改變 – OsamaKhalid

1

你的方法很漫長,令人困惑,很難調試,而且從我看到它不是很好的性能方面(請查看contains方法)。檢查此:

String[] words = {"a", "ab", "ad", "abc", "af", "b", "dsadsa", "c", "ghh", "po"}; 
Map<Integer, List<String>> groupByLength = 
    Arrays.stream(words).collect(Collectors.groupingBy(String::length)); 
System.out.println(groupByLength); 

這只是一個例子,但你明白了。我有一組單詞,然後我使用流和魔法將它們按照長度(正是你想要做的)分組在一張地圖中。你得到流,然後收集到一個地圖,根據單詞的長度分組,所以它會把每個1個字母的單詞列在關鍵字1之下等。

你可以使用相同的方法,但你有你的所以記得在列表中不要使用Arrays.stream(),而只是使用.stream()

+0

好吧我打算從現在開始使用流..良好的迴應 – OsamaKhalid