2014-12-03 5 views
1

В моем проекте пользователь вводит случайные буквы. Затем я перебираю my_list, чтобы увидеть, есть ли какая-либо из этих случайных букв в my_list. Если это так, я удаляю их с my_list.Iterator not looping

Пример:

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

ответ

4

Попробуйте создать Iterator внутри для цикла.

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

Я попробую. почему это было приостановлено? – user2456977

+0

Я действительно не понимаю, почему люди занижают некоторые ответы, которые, по-видимому, не ошибаются, и даже не оставляют комментариев, объясняя почему ... –

0
i.remove(); 

вот ваша проблема. вы должны удалить его из my_list, как вы объяснили.

поэтому используйте

my_list.remove(); 
0

Или просто использовать один лайнер:

my_list.removeAll(rand); 

Вы также можете использовать способность Листа, чтобы удалить объекты равенством:

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

любая идея, почему это было приостановлено? Я думаю, что removeAll дал мне ошибку, поэтому я должен был быть более конкретным и перебирать каждый элемент в списке. Но я могу попробовать еще раз. – user2456977

+0

Кто знает - в stackoverflow есть некоторые странные люди. Мне было бы интересно узнать, что это за ошибка. – BarrySW19

+0

Функция removeAll() легко может быть наиболее эффективной, поскольку она должна выполнять поиск только по базовым данным «my_list». – BarrySW19

2

Проблема в том, что в вашей внутренней петле вы достигаете конца i-го итератора с первой итерацией внешнего контура. Затем, когда вторая итерация начала начинается, итератор i hasNext всегда возвращает false, и кажется, что ничего не сделано, как вы сказали.

Вы должны повторно инициализировать я итератор для каждого нового с из ваших для

+0

, так что просто положите его в мой цикл? – user2456977

+0

есть, это правильно !! – jesantana

0

Вам необходимо сбросить итератор к его началу перед циклом через к следующему пункту.

0

Один раз вы можете пройти через Итератор.Подумайте об этом: однажды 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); 
     } 
    } 
}