2014-12-03 104 views
1

在我的項目中,用戶輸入隨機字母。然後我遍歷my_list,看看這些隨機字母是否出現在my_list。如果是這樣,我從my_list中刪除它們。迭代器不循環

實施例:

List<String> my_list包含:[a, b, c, d]

List<String> rand包含:[r, a]

目標:a將從my_list

問題被移除:將Iterator循環通過my_list用於字母搜索r。字母r不在my_list。但是,而不是繼續到下一個字母a,該iterator退出循環和a仍停留在my_list

有人能告訴我爲什麼我的循環保持的第一個字母后分手?

這裏是我的代碼:

public void removeLetters(List<String> my_list, List<String> rand) { 
    Iterator<String> i = my_list.iterator(); 
    for(String s : rand) { 
     while(i.hasNext()) { 
      Object o = i.next(); 
      if(o.toString().equals(s)) { 
       i.remove(); 
       i = my_list.iterator(); 
       break; 
      } 
     } 
    } 
} 

我希望我解釋了我的問題不夠好。如果我需要更詳細地解釋,請告訴我。

謝謝

+0

爲什麼不使用'my_list.removeAll(rand);'? – 323go 2014-12-03 16:28:04

回答

4

嘗試在for循環中創建Iterator

for(String s : rand) { 
    Iterator<String> i = my_list.iterator(); 
    while(i.hasNext()) { 
     ... 
    } 
} 
+0

我會試試。爲什麼這是低調? – user2456977 2014-12-03 16:31:28

+0

我真的不明白爲什麼人們downvote顯然沒有錯的一些答案,甚至沒有留下評論,解釋爲什麼... – 2014-12-03 16:38:46

0
i.remove(); 

這裏是你的問題。你必須按照你的解釋從my_list中移除它。

所以使用

my_list.remove(); 
0

或者,只需使用一個襯墊:

my_list.removeAll(rand); 

你也可以使用List的能力平等刪除對象:

for(String s: rand) { 
    my_list.remove(s); 
} 

如果您想要迭代,這正是java.util.AbstractCollection所做的:

Iterator<String> it = my_list.iterator(); 
while (it.hasNext()) { 
    if (rand.contains(it.next())) { 
     it.remove(); 
    } 
} 
+0

任何想法,爲什麼這是downvoted?我認爲removeAll給了我一個bug,所以我必須更具體一些,並遍歷列表中的每個項目。但我可以再試一次。 – user2456977 2014-12-03 16:29:50

+0

誰知道 - 在stackoverflow上有一些奇怪的人。我很想知道這個bug是什麼。 – BarrySW19 2014-12-03 16:38:31

+0

removeAll()方法最爲高效,因爲它只需搜索一次底層的「my_list」數據。 – BarrySW19 2014-12-03 16:44:58

2

問題是,在你的內循環中,你通過外循環的第一次迭代到達迭代器的末端。然後,當開始第二次迭代時,迭代器中的hasNext方法總是返回false,似乎沒有任何事情可以做,就像你說的那樣。

你應該重新初始化我迭代器爲你的每一個新的S代表

+0

所以只是把它放在我的循環? – user2456977 2014-12-03 16:30:54

+0

是的,這是正確的! – jesantana 2014-12-03 16:31:20

0

您需要爲下一個項目通過循環之前,迭代器重置爲開頭。

0

你只能通過一次Iterator。想一想:一旦i.hasNext()返回false,你會掉出內循環,圍繞外循環再次呼叫i.hasNext()。爲什麼現在開始返回true? 底線:你必須創建一個新的迭代器每次重新啓動外循環時間(基本動環內my_list.iterator()調用) 更重要的是,通過列表迭代一次,輸入列表上使用:

for(Iterator it = my_list.iterator(); it.hasNext();) { 
    if(rand.contains(it.Next()) { 
     it.remove(); 
    } 
} 

如果輸入列表(rand)可能足夠大以至於不重要,則可能需要在循環前將其轉換爲集合:rand = new HashSet(rand);這會使您的算法呈線性而非二次方式。

0

你有沒有理由不使用包含?

public void removeLetters(List<String> my_list, List<String> rand) 
{ 
    List<String> updatedList = new ArrayList<String>(); 

    for (String s : my_list) 
    { 
     if (!rand.contains(s)) 
     { 
      updatedList.add(s); 
     } 
    } 
}