Я столкнулся с требованием, когда мне нужна очередь, которая
(1) ведет себя как peek
метод, но также должна переместить head
к следующему элементу
(2) позволяет offer
ставить в очередь во время итерации без ConcurrentModificationException
.
Итак, вот что я придумал
SpecialPeekOpQueue.java
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
public class SpecialPeekOpQueue<T> {
ListIterator<T> listIterator;
int movingFrontIndex;
List<T> list;
public SpecialPeekOpQueue() {
movingFrontIndex = 0;
list = new LinkedList<T>();
listIterator = list.listIterator();
}
public boolean hasActiveItems () {
return movingFrontIndex < list.size();
}
public T specialPeek() {
if (movingFrontIndex >= list.size()) {
return null;
}
return list.get(movingFrontIndex++);
}
public void offer(T t) {
listIterator.add(t);
}
public List<T> getActiveItems() {
return list.subList(movingFrontIndex, list.size());
}
public List<T> getAllItems() {
return list;
}
}
CustomQueueTest.java
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.ailo.util.collections.SpecialPeekOpQueue;
public class SpecialPeekOpQueueTest {
@Test
public final void testOfferAndPeek() {
SpecialPeekOpQueue<String> queue = new SpecialPeekOpQueue<String>();
queue.offer("one");
assertEquals ("[one]", ""+ queue.getActiveItems());
assertEquals(true, queue.hasActiveItems());
assertEquals ("[one]", ""+queue.getAllItems());
queue.offer("two");
assertEquals(true, queue.hasActiveItems());
assertEquals ("[one, two]", ""+queue.getActiveItems());
assertEquals ("[one, two]", ""+queue.getAllItems());
queue.offer("three");
assertEquals(true, queue.hasActiveItems());
assertEquals ("[one, two, three]", ""+queue.getActiveItems());
assertEquals ("[one, two, three]", ""+queue.getAllItems());
assertEquals("one", queue.specialPeek());
assertEquals(true, queue.hasActiveItems());
assertEquals ("[two, three]", ""+queue.getActiveItems());
assertEquals ("[one, two, three]", ""+queue.getAllItems());
assertEquals("two", queue.specialPeek());
assertEquals(true, queue.hasActiveItems());
assertEquals ("[three]", ""+ queue.getActiveItems());
assertEquals ("[one, two, three]", ""+queue.getAllItems());
assertEquals("three", queue.specialPeek());
assertEquals(false, queue.hasActiveItems());
assertEquals ("[]", ""+ queue.getActiveItems());
assertEquals ("[one, two, three]", ""+queue.getAllItems());
assertEquals(null, queue.specialPeek());
}
@Test
public final void testModifyWhileIterate() {
SpecialPeekOpQueue<String> queue = new SpecialPeekOpQueue<String>();
queue.offer("one");
queue.offer("two");
queue.offer("three");
for (int i=0; i< queue.getAllItems().size(); i++) {
if (i==1) {
queue.offer("four");
}
}
assertEquals(true, queue.hasActiveItems());
assertEquals ("[one, two, three, four]", ""+ queue.getActiveItems());
assertEquals ("[one, two, three, four]", ""+queue.getAllItems());
assertEquals("one", queue.specialPeek());
}
}
Есть ли какие-либо стандартные реализации Java, доступные для достижения того же?Буду признателен за ваши мысли и предложения.