我正在迭代java.util.LinkedList,在某些情况下我会添加一个元素。
LinkedList<Schedule> queue = new LinkedList<Schedule>(schedules);
ListIterator<Schedule> iterator = queue.listIterator();
while (iterator.hasNext()) {
Schedule schedule = iterator.next();
if(condition)
iterator.add(new Schedule());
}
问题在于,如果我以一个项目开始,则在下一个iterator.next()调用之前添加新项目并退出迭代。
如何在迭代时将项目附加到LinkedList的末尾? 请不要告诉我使用另一个列表并在第一个列表之后重复它,因为它无法正确解决我的问题。
答案 0 :(得分:1)
如果你不能使用另一个列表,你可以通过保留通过迭代器处理的元素数量的计数来解决你的问题,并将其与列表的原始大小进行比较:所有新元素都将在列表,所以你可以在达到原始大小时结束循环。
LinkedList<Schedule> queue = new LinkedList<Schedule>(schedules);
int origSize = queue.size();
int currCount = 0;
ListIterator<Schedule> iterator = queue.listIterator();
while (iterator.hasNext()) {
++currCount;
if (currCount >= origSize) {
break; // reached the end of the original collection
}
Schedule schedule = iterator.next();
if(condition)
iterator.add(new Schedule());
}
您还可以使用额外的列表来跟踪新元素,并在处理结束后将其添加到原始列表中:
LinkedList<Schedule> queue = new LinkedList<Schedule>(schedules);
LinkedList<Schedule> addQueue = new LinkedList<Schedule>();
ListIterator<Schedule> iterator = queue.listIterator();
while (iterator.hasNext()) {
Schedule schedule = iterator.next();
if(condition)
addQueue.add(new Schedule());
}
queue.addAll(addQueue);
另请注意iterator.add()
将指定的元素插入列表(可选操作)。该元素将紧接在next将返回的下一个元素之前插入(如果有),并且在之前返回的下一个元素(如果有)之后插入。 (如果列表中不包含任何元素,则新元素将成为列表中的唯一元素。)新元素在隐式游标之前插入:对next的后续调用不受影响,后续调用previous将返回新元素。 (此调用将调用nextIndex或previousIndex返回的值增加1。)
因此,如果列表中有多个元素,则不会将新元素添加到结尾,而是添加当前元素和next()
返回的元素。如果您确实要将新元素放在列表的末尾,请使用queue.add(...)
一般情况下,不建议在通过迭代器遍历它时修改集合,所以我建议你使用第二种方法(在单独的列表中收集额外的元素并在最后将它们添加到原始集合中)
答案 1 :(得分:1)
假设您没有使用迭代器的硬性要求,那么您可以将其搁置并通过索引在列表上“迭代”:
LinkedList<Schedule> list;
for (int i = 0; i < list.size(); i++) {
final Schedule schedule = list.get(i);
if(condition)
list.add(new Schedule());
}
答案 2 :(得分:0)
如何将项目附加到LinkedList的末尾 迭代?
public void addWork(Scheduler scheduler)
{
synchronized(scheduler)
{
queue.addLast(scheduler);
}
}
您可以使用queue.removeFirst()
从上到下处理队列中的项目。
public synchronized Scheduler getWork()
{
return queue.removeFirst();
}
编辑。
答案 3 :(得分:0)
正如其他人所建议的那样,当前Collections框架在迭代过程中没有对端插入的有效,现成的支持。一个建议涉及重写迭代器。但是我说,为什么不走得更远呢?
使用反射来修改Node
类的可访问性,该类为您提供了对双链接的引用,因此您无需从get(index)
开始迭代,这应该用于性能代码。
从LinkedList
继承/派生并明智地覆盖。
这是显而易见的,但出于上述2的精神,由于JDK是开源的,因此可以根据需要借用源代码并编写自己的实现。
无论哪种情况,我真的觉得该功能应该由Java LinkedList API提供。
答案 4 :(得分:-1)
只有在不使用迭代器进行迭代时,才能满足迭代中添加并在迭代中包含添加项的要求,因为每次元素都无法重新计算迭代器的状态添加。如果您接受效率较低的get
方法进行迭代,则问题很简单。例如
LinkedList<Schedule> queue = new LinkedList<Schedule>(){{add(new Schedule());add(new Schedule());add(new Schedule());}};
int i = 0;
// queue.size() is evaluated every iteration
while (i < queue.size()) {
Schedule schedule = queue.get(i);
if(i++ % 2 == 0)
queue.add(new Schedule());
}
System.out.println(queue.size());
按预期打印6个。