我正在两个列表上执行迭代。
// 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
,因为这样可以将项目从item
移除以供下次迭代。
来自itemIterator
的一个event
只能由eventIterator
中的一个itemIterator
声明。因此,在声明之后将该项目保留在迭代中是没有意义的。因此,我从gradlew clean
删除了该项目。
如果他们减少迭代次数而不是传统的for-each循环,我愿意接受替代方案。
答案 0 :(得分:4)
如何在不使用
itemIterator
重新启动items.iterator()
的情况下将itemIterator
重置为0位置,因为这样可以将项目从itemIterator.remove()
移除以供下次迭代。
不,它不会。 next()
从您获取迭代器的集合中删除该项,而不仅仅是迭代器。如果从该集合中获得一个新的迭代器,它就不再有该项了;你删除了它。来自the JavaDoc:
从底层集合中删除此迭代器返回的最后一个元素(可选操作)。每次调用
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();
// ...
}
内获得一个新的。
#include <fstream>
int main()
{
std::ofstream ("Hello.txt");
return 0;
}
答案 1 :(得分:2)
使用像这样的嵌套循环是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用作地图的键
,这可能会更有效e.g。
Map<String, Event> events = ... // events keyed by id
Map<String, EventItem> items = ... // event items keys by eventId
events.keySet().removeAll(items.keySet());