2012-04-27 5 views
1

java.util.LinkedListを反復処理している場合がありますが、場合によっては要素を追加しています。反復処理中にJava 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の最後にアイテムを追加するにはどうすればよいですか? 別のリストを使用して最初の後にそれを繰り返しても、問題が正しく解決されないので、それを繰り返さないようにしてください。

+1

ただ好奇心で、正式に別のリストを使用しないでください。 – UmNyobe

+0

明らかにはありませんが、反復処理中に追加したいのは、反復処理中に新たに追加された要素も処理する必要があるためです。これが最短の方法である可能性があります。 –

+0

いくつかの良い答えがあるhttps://stackoverflow.com/questions/993025/java-adding-elements-to-a-collection-during-iterationの重複 –

答えて

2

別のリストを使用できない場合は、イテレータを使用して処理した要素の数をカウントし、リストの元のサイズと比較することで問題を解決できます。新しい要素はすべて、リストには、元のサイズに達したときにループを終了することができます。

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()

に注意してください:あなたはまた、新しい要素を追跡し、処理が終わった後に元のリストにそれを追加するために、余分なリストを使用することができ

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()); 
} 

指定された要素をリストに挿入します(オプションの操作)。要素は、次の要素がある場合にはそれが返される次の要素の直前に挿入され、存在する場合には前の要素によって返される次の要素の後に挿入されます。 (リストに要素が含まれていない場合は、新しい要素がリスト上の唯一の要素になります)。暗黙的カーソルの前に新しい要素が挿入されます:nextへの次の呼び出しは影響を受けず、 。

リストに複数の要素がある場合、最後に新しい要素を追加することはありませんが、現在のものとnext()によって返されたものの間のものです。リストの最後に新しい要素を配置する場合は、queue.add(...)

一般的に、イテレータを介してコレクションをトラバースしてコレクションを変更することはお勧めできませんので、2番目の方法を使用することをお勧めします余分な別のリスト内の要素と終了時に元に追加) を反復しながら、私はのLinkedListの末尾に項目を追加するにはどうすればよい

+0

あなたが言っていることは本当ですが、繰り返し中に新しい追加要素も処理する必要があるため、反復中に追加したいという問題があります。だから、おそらく私は他のリストを使用して回避策を見つける必要があります。 –

+0

ちょうど挿入された新しい要素にアクセスしたい場合、 'iterator.previous()'を呼び出すことができます(答えに引用符で囲まれたテキストを参照してください)。 – Attila

0

public void addWork(Scheduler scheduler) 
{ 
synchronized(scheduler) 
{ 
    queue.addLast(scheduler); 
} 
} 

、あなたは上から下から、キュー内のアイテムに対処するqueue.removeFirst()を使用することができます。

public synchronized Scheduler getWork() 
{ 
    return queue.removeFirst(); 
} 

編集。反復しながら、要件を追加する

LinkedList<Schedule> list; 

for (int i = 0; i < list.size(); i++) { 
    final Schedule schedule = list.get(i); 
    if(condition) 
     list.add(new Schedule()); 
} 
+0

しかし、反復中にこれを行うと、ConcurrentModificationExceptionが発生します。 –

+0

編集:追加/取得作業を行うための別個の同期メソッド。 – Bitmap

2

イテレータを追加するたびにイテレータの状態を再計算する方法がないため、イテレータをイテレータとして使用しないと、反復の追加項目は満たされません。効率の悪い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()); 

prints 6が期待どおりに表示されます。

+1

+1:しかし、 'list.get(i)'は一般的にリンクリストでは良くありません。 –

+0

はい、わかっていますが、反復処理中にリストに追加するのは一般的には悪い考えです。しかし、これはおそらくOPが(直進的な)解決策に近づくだろう。 – Perception

0

をし、含まれます:あなたは、あなただけの代わりに、インデックスリストの上に「反復」を棚上げすることができますイテレータを使用するのは難しいの要件を持っていないと仮定すると、

関連する問題