我正在对两个列表进行迭代。
// 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
已经结束了。
如何在不使用items.iterator()
重新启动itemIterator
来定位0
,因为这将从itemIterator
中删除的项目恢复为下一次迭代。
来自itemIterator
的一个item
只能由eventIterator
的一个event
认领。因此,在声明该项目后将其保留为迭代对我来说是没有意义的。因此,我从itemIterator
中删除了该项目。
如果它们比传统的 for-each 循环减少迭代次数,我愿意接受替代方案。
如何在不使用
items.iterator()
重新启动itemIterator
的情况下将重置为位置 0,因为这将从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();
// ...
}
使用这样的嵌套循环是 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);
如果将 id 用作地图的键,这可能会更有效
例如
Map<String, Event> events = ... // events keyed by id
Map<String, EventItem> items = ... // event items keys by eventId
events.keySet().removeAll(items.keySet());