2016-07-26 2 views
0

Я продолжаю сбой и получаю java.util.NoSuchElementException в инструкции if. У меня создалось впечатление, что while (Iterator.hasNext()) гарантирует, что вызов Iterator.next() не вызовет переполнение буфера.Удаление элемента из внутреннего вложенного Iterator в java вызывает NoSuchElementException

Что такое правильный алгоритм перебора два вложенных друг в друг итераторов, и удалить элементы из одного из итераторы, когда найдено совпадение, не бросает такое исключение (который я думаю вызвано обгонной границу массива)?

введите код здесь {

Iterator<Integer> d = entitiesDeleteQueue.iterator(); 
    Iterator<Entity> e = entities.iterator(); 


    while (d.hasNext()) { 

     while (e.hasNext()) { 

      if (d.next() == e.next().getEntityId()) 

       e.remove(); 
     } 
    } 
} 
+0

Вы должны точно рассмотреть, что произойдет, если 'сущности' имеют три элемента, а' entitiesDeleteQueue' - два. Возможно, вы захотите запустить его на бумаге. –

+0

d.next() будет переполняться на последней итерации e.hasNext(). Спасибо. – DayTripperID

+0

Кроме того, я вижу, что я продвигаю самый внешний итератор внутри цикла каждый раз, когда вызывается next(). Эффект, который я хочу, - это вложенный цикл, где каждая итерация внешнего цикла сравнивает один внешний элемент с каждым внутренним элементом. Чтобы достичь этого, мне пришлось бы вызывать элемент итератора внешнего цикла, не продвигая его, пока я во внутреннем цикле. Есть ли способ достичь этого? – DayTripperID

ответ

0

Вы должны объединить два hasNext условия, чтобы избежать перерасхода либо итератора:

while (d.hasNext() && e.hasNext()) { 
    if (d.next() == e.next.getEntityId()) 
     e.remove(); 
} 
0

Проблема в том, что гнездовые итераторы не так просто, как гнездование для петель. Для этого требуется присвоить Iterator.next() ссылку на объект, таким образом, итератор не продвигается каждый раз, когда вам нужно получить доступ к элементу. Ссылка должна выполняться в каждом слое гнезда, а второй итератор должен быть создан внутри внешнего цикла. Затем вы можете выполнять операции, не перегружая ArrayList слишком многими next() вызовами.

List<Entity> entities = new ArrayList<Entity>(); 
List<Entity> entityDeleteQueue = new ArrayList<Entity>(); 

Iterator<Entity> e = entities.iterator(); 

    while (e.hasNext()) { 

     Entity liveEntity = e.next(); 
     Iterator<Entity> d = entityDeleteQueue.iterator(); 

     while (d.hasNext()) { 

      Entity deadEntity = d.next(); 

      if(deadEntity.getEntityId() == liveEntity.getEntityId()){ 

       System.out.println("Dead entity: " + deadEntity.getEntityId()); 

       System.out.println("Removing entity " + liveEntity.getEntityId()); 

       e.remove(); 
      } 
     } 
    } 

    for (Entity survivor: entities){ 

     System.out.println("Remaining entity: " + survivor.getEntityId()); 
    } 

 Смежные вопросы

  • Нет связанных вопросов^_^