2017-01-27 89 views
0

我有一個HashMap,鍵的值是一個ArrayList。當我逐行讀取文件時,我需要添加到屬於該特定鍵的ArrayList。 該文件可能有1行或100萬行,關鍵名稱將是行(String),它的值將表示它在文件中出現的行號。如何添加到迭代時是一個HashMap值的ArrayList?

有人可以幫我嗎?此外,這是快速的時間複雜性明智嗎?如果不是,我該如何優化它?

例的test.txt:

Hello  <== Line 0 
Jello  <== Line 1 
Mello  <== Line 2 
Hello  <== Line 3 
Tello  <== Line 4 
Jello  <== Line 5 
Tello  <== Line 6 
Tello  <== Line 7 

我需要我的地圖存儲內容(忽略順序):

{"Hello": [0, 3]} 
{"Jello": [1, 5]} 
{"Mello": [2]} 
{"Tello": [4, 6, 7]} 

我的代碼是:

ArrayList<Integer> al = new ArrayList<Integer>(); 
Map<String, ArrayList<Integer>> hm = new HashMap<String, ArrayList<Integer>>(); 

int num = 0; 
for (String line = file.readLine(); line != null; line = file.readLine()) { 
    map.put(line, al.add(num)); <== the issue is here, how to fix? 
} 

編譯器錯誤:

incompatible types: boolean cannot be converted to ArrayList<Integer> 
+0

調用'al.add(num);'作爲一個單獨的語句,然後使用'map.put(line,num);' – MadProgrammer

回答

1

的ArrayList的add函數返回表示成功或失敗的一個布爾值。這就是你遇到錯誤的原因。您必須先將您的編號添加到列表中,然後將列表放入地圖中。但是在你的代碼中有一個不同的問題。您將一遍又一遍地添加相同的列表到所有的鍵。

試試這個代碼:

Map<String, ArrayList<Integer>> hm = new HashMap<String, ArrayList<Integer>>(); 
int currentLineNumber = 0; 
for (String line = file.readLine(); line != null; line = file.readLine()) { 

    if(!hm.containsKey(line)) 
    { 
     hm.put(line, new ArrayList<Integer>()); 
    } 

    hm.get(line).add(currentLineNumber); 

    currentLineNumber++; 
} 
+0

ArrayList的add方法將始終返回true,但這是一種挑剔。 https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#add(E) – coolioasjulio

+0

它會的。但是布爾的含義來自底層集合https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html#add(E) – Reasurria

1

你的問題是數組列表上的add方法返回一個布爾值。

您正試圖做一個「一致性」應用程序,並且很容易在Java中爲此解決方案進行網絡搜索。這個問題的其他答案做了很好的說明。

至於你的複雜性問題,使用一個哈希映射關鍵字是單詞,其值是行數組列表是非常好的(並且應該有接近最佳的複雜性,因爲每個行過程需要攤銷不變的時間)。然而,只要一切都適合內存,情況就是這樣!如果你的文件文件進入gazillions,你可以使用中間文件來完成一個好的map-reduce框架的一致性。

+0

這是一個很好的解釋。我很高興我認爲它是正確的。謝謝! – udpcon

5

爪哇8:

map.computeIfAbsent(line, k -> new ArrayList<>()).add(num); 

爪哇7:

ArrayList<Integer> values = map.get(line); 
if (values == null) { 
    map.put(line, values = new ArrayList<>()); 
} 
values.add(num); 
+0

這不適合我。列表的長度是正確的,但其元素總是0. – udpcon

+0

@udpcon只是values.add(num ++) – Reasurria

+1

@udpcon顯然你必須增加num。這不是問題。 – shmosel

0

你正在做的是將整數HashMap的關鍵,而不是整個ArrayList的

嘗試是這樣的:

  Map<String, ArrayList<Integer>> hm = new HashMap<String, ArrayList<Integer>>(); 

      String key=""; 
      while(file.readLine()!=null){ 
       key=file.readLine(); 
     ArrayList<Integer> al = new ArrayList<Integer>(); 

      OUT: for (String line = file.readLine(); line != null; line = file.readLine()) { 
if(key.equals(line)){ 
       al.add(num); 
    } 
    else{ 
    break OUT; 
} 
} 
      map.put(key, al); 
     } 

該解決方案是沒有經過測試,但我認爲這將工作。

+0

這看起來不像它會編譯。 – Reasurria

+0

我忘了添加一個右括號,而..我糾正了..現在 –

+0

不,我的意思是「鍵=線」。行僅限於for循環。 – Reasurria

0
Integer num = 0; 
for (String line = file.readLine(); line != null; line = file.readLine()) { 

    if(!hm.containsKey(line)) 
    { 
     hm.put(line, new ArrayList<Integer>()); 
    } 

    hm.get(line).add(num); 

    num++; 
} 

我認爲這應該工作。

相關問題