2013-06-03 54 views
0

我試圖從兩個文件讀入並將它們存儲在兩個單獨的數組列表中。這些文件由單獨在一行上的單詞或用逗號分隔的多行文字組成。 我讀下面的代碼(不完整)的每個文件:remove對arraylist的所有操作都會使程序掛起

ArrayList<String> temp = new ArrayList<>(); 

FileInputStream fis; 
fis = new FileInputStream(fileName); 

Scanner scan = new Scanner(fis); 

while (scan.hasNextLine()) { 
    Scanner input = new Scanner(scan.nextLine()); 
    input.useDelimiter(","); 
    while (scan.hasNext()) { 
     String md5 = scan.next(); 
     temp.add(md5); 
    } 
} 
scan.close();  

return temp; 

每個文件都包含近100萬字(我不知道確切的數字),所以我不能完全肯定的是,上面的代碼工作正常 - 但似乎。

我現在想知道第一個文件/數組列表中有多少個單詞是獨佔的。爲此,我計劃使用list1.removeAll(list2),然後檢查list1的大小 - 但出於某種原因,這不起作用。代碼:

public static ArrayList differentWords(String fileName1, String fileName2) { 
    ArrayList<String> file1 = readFile(fileName1); 
    ArrayList<String> file2 = readFile(fileName2); 

    file1.removeAll(file2); 

    return file1; 
} 

我主要的方法中包含幾個不同的電話,直到我到了上面的代碼,剛剛導致程序掛起(在它只是「跑」的NetBeans)一切工作正常。
任何想法爲什麼會發生這種情況?

+1

這聽起來像一個非常沉重的操作,可能只需要永遠完成。我認爲你應該重新考慮你的方法。 – Keppil

+2

我想你的意思是'while(input.hasNext()){'? – Djon

+4

使用'HashSet'而不是'ArrayList'可能會加快速度。 – Kai

回答

1

您還沒有

while (scan.hasNextLine()) { 
    Scanner input = new Scanner(scan.nextLine()); 
    input.useDelimiter(","); 
    while (scan.hasNext()) { 
    String md5 = scan.next(); 
    temp.add(md5); 
    } 
} 

使用input我想你的意思是這樣:

while (scan.hasNextLine()) { 
    Scanner input = new Scanner(scan.nextLine()); 
    input.useDelimiter(","); 
    while (input.hasNext()) { 
    String md5 = input.next(); 
    temp.add(md5); 
    } 
} 

而是說你應該看看String#split(),可能會節省您的時間:

while (scan.hasNextLine()) { 
    String line = scan.nextLine(); 
    String[] tokens = line.split(","); 
    for (String token: tokens) { 
    temp.add(token); 
    } 
} 
+0

這裏花費的時間是'file1.removeAll(file2);''file1'和'file2'是巨大的'ArrayList's。如果它能節省時間,你的解決方案可能甚至不會節省一整秒。 – jlordo

+0

在它掛起的問題,這意味着它不工作,可能是因爲我指出了什麼?當他/她的計劃有效時,他/她可以問爲什麼它很慢。 – Djon

+1

從OP:*「我不完全確定上面的代碼是否正常工作 - 但它似乎是」*。以下是它出錯的地方:首先在一個小輸入集上測試你的程序,並確保它是**正確的**!顯然,使用**錯誤的'Scanner' **使任何試圖「優化成本」的嘗試都是徒勞的。至於實際的優化,使用'HashSet'代替'ArrayList'將'removeAll'的複雜度從'O(n^2)'降低到'O(n)',這會導致相當快的速度 - 向上。 –

-1

試試這個:

for(String s1 : file1){ 
    for(String s2 : file2){ 
     if(s1.equals(s2)){file1.remove(s1))} 
    } 
} 
+2

這相當於未經優化的'removeAll'(即忽略使用集合類型(如Set)的優化)。另外,它會因'ConcurrentModificationException'而失敗,因爲你直接在循環內部修改'file1'(而不是使用'Iterator.remove')。 –

相關問題