Сброс позиции итератора до 0 во вложенном цикле while - PullRequest
0 голосов
/ 25 мая 2018

Я выполняю итерацию по двум спискам.

// events and items are two lists.

Iterator<Event> eventIterator = events.iterator();
Iterator<EventItem> itemIterator = items.iterator();

while (eventIterator.hasNext()) {

    Event event = eventIterator.next();

    while (itemIterator.hasNext()) {

        EventItem item = itemIterator.next();

        if (event.getId().equals(item.getEventId())) {

            // CLAIMED
            itemIterator.remove();
        }
    }

    // PROBLEM IS HERE.

}

Проблема:

Я перебрал itemIterator до конца, а также удалил элементы изitemIterator если предмет востребован.Но когда будет запущена следующая итерация на eventIterator, itemIterator уже в ее конце.

Как я могу сбросить itemIterator в положение 0, не переинициализируя его с помощью items.iterator(), потому что это вернет элементы, удаленные из itemIterator для следующей итерации.

One itemот itemIterator может быть заявлен только один event от eventIterator.Поэтому для меня нет смысла держать этот элемент в итерации после того, как он будет востребован.Следовательно, я удаляю элемент из itemIterator.

. Я открыт для альтернатив, если они уменьшают количество итераций по сравнению с традиционным циклом for-each.

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

Использование таких вложенных циклов - O (N * M) и дорого, но это также многословно, что скрывает цель того, чего вы пытаетесь достичь.Я предлагаю вам использовать потоки из Java 8.

// get all the event's ids
Set<String> eventIds = events.stream()
        .map(Event::getId)
        .collect(Collectors.toSet());

// remove the entries from items with a matching id.
items.removeIf(i -> eventIds.contains(i.getEventId()));

Это имеет временную сложность O (N + M).

И удаленные / заявленные элементы добавляются к другомусписок (я называю это EventDto, объект передачи данных)

Вы можете сделать это, сначала создав список.

// remove the entries from items with a matching id.
List<EventItem> toMove = items.stream()
                              .filter(i -> eventIds.contains(i.getEventId()))
                              .collect(Collectors.toList());
items.removeAll(toMove);
anotherList.addAll(toMove);

Это может быть более эффективным, если идентификаториспользовался в качестве ключа карты

например

Map<String, Event> events = ... // events keyed by id
Map<String, EventItem> items = ... // event items keys by eventId

events.keySet().removeAll(items.keySet());
0 голосов
/ 25 мая 2018

Как я могу сбросить itemIterator в положение 0, не переинициализируя его с помощью items.iterator(), потому что это вернет элементы, удаленные из itemIterator для следующей итерации.

Нет, этоне будет.itemIterator.remove() удаляет элемент из коллекции , с которой вы получили итератор, а не только итератор.Если вы получите новый итератор из этой коллекции, на нем больше не будет этого элемента;Вы удалили это.С JavaDoc :

Удаляет из базовой коллекции последний элемент, возвращаемый этим итератором (необязательная операция).Этот метод можно вызывать только один раз за вызов next().

(мой акцент)

Вы не можете сбросить итератор;просто получите новый, в пределах while.

Iterator<Event> eventIterator = events.iterator();

while (eventIterator.hasNext()) {
    Event event = eventIterator.next();

    Iterator<EventItem> itemIterator = items.iterator();
    while (itemIterator.hasNext()) {
        EventItem item = itemIterator.next();
        if (event.getId().equals(item.getEventId())) {
            // CLAIMED
            itemIterator.remove();
        }
    }

    // If you need to loop a second time for some reason:
    itemIterator = items.iterator();
    // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...