forked from I2P_Developers/i2p.i2p
Move CachedIteratorArrayList from core to router
This commit is contained in:
@ -1,109 +0,0 @@
|
||||
package net.i2p.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* ArrayList that uses a single iterator. Useful to avoid object churn
|
||||
* while keeping the conveniences of an iterator.
|
||||
*
|
||||
* @since 0.9.4
|
||||
*
|
||||
* @author zab
|
||||
*/
|
||||
public class CachedIteratorArrayList<E> extends ArrayList<E> {
|
||||
|
||||
private static final long serialVersionUID = 4863212596318574111L;
|
||||
|
||||
private final CachedIterator iterator = new CachedIterator();
|
||||
|
||||
public CachedIteratorArrayList() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CachedIteratorArrayList(Collection<? extends E> c) {
|
||||
super(c);
|
||||
}
|
||||
|
||||
public CachedIteratorArrayList(int initialCapacity) {
|
||||
super(initialCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
iterator.reset();
|
||||
return iterator;
|
||||
}
|
||||
|
||||
private class CachedIterator implements Iterator<E>, Serializable {
|
||||
/**
|
||||
* Index of element to be returned by subsequent call to next.
|
||||
*/
|
||||
int cursor = 0;
|
||||
|
||||
/**
|
||||
* Index of element returned by most recent call to next or
|
||||
* previous. Reset to -1 if this element is deleted by a call
|
||||
* to remove.
|
||||
*/
|
||||
int lastRet = -1;
|
||||
|
||||
/**
|
||||
* The modCount value that the iterator believes that the backing
|
||||
* List should have. If this expectation is violated, the iterator
|
||||
* has detected concurrent modification.
|
||||
*/
|
||||
int expectedModCount = modCount;
|
||||
|
||||
void reset() {
|
||||
cursor = 0;
|
||||
lastRet = -1;
|
||||
expectedModCount = modCount;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return cursor != size();
|
||||
}
|
||||
|
||||
public E next() {
|
||||
checkForComodification();
|
||||
try {
|
||||
int i = cursor;
|
||||
E next = get(i);
|
||||
lastRet = i;
|
||||
cursor = i + 1;
|
||||
return next;
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
checkForComodification();
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if (lastRet < 0)
|
||||
throw new IllegalStateException();
|
||||
checkForComodification();
|
||||
|
||||
try {
|
||||
CachedIteratorArrayList.this.remove(lastRet);
|
||||
if (lastRet < cursor)
|
||||
cursor--;
|
||||
lastRet = -1;
|
||||
expectedModCount = modCount;
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
|
||||
final void checkForComodification() {
|
||||
if (modCount != expectedModCount)
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
package net.i2p.util;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class CachedIteratorArrayListTest {
|
||||
|
||||
private List<Character> l;
|
||||
private Iterator<Character> iter;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
l = new CachedIteratorArrayList<Character>();
|
||||
l.add('a');
|
||||
l.add('b');
|
||||
l.add('c');
|
||||
iter = l.iterator();
|
||||
}
|
||||
|
||||
/** test iterations work */
|
||||
@Test
|
||||
public void test() {
|
||||
String total = "";
|
||||
|
||||
// two full for-each iterations
|
||||
for (char i : l)
|
||||
total += i;
|
||||
assertEquals("abc", total);
|
||||
for (char i : l)
|
||||
total += i;
|
||||
assertEquals("abcabc", total);
|
||||
|
||||
// and one partial
|
||||
total = "";
|
||||
iter = l.iterator();
|
||||
total += iter.next();
|
||||
total += iter.next();
|
||||
iter = l.iterator();
|
||||
total += iter.next();
|
||||
assertEquals("aba",total);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameness() {
|
||||
Iterator<Character> two = l.iterator();
|
||||
Iterator<Character> one = l.iterator();
|
||||
assertSame(one, two);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove() {
|
||||
iter.next();
|
||||
iter.remove();
|
||||
|
||||
// test proper removal
|
||||
assertEquals(2,l.size());
|
||||
assertEquals('b',l.get(0).charValue());
|
||||
assertEquals('c',l.get(1).charValue());
|
||||
|
||||
// test iterator still workx after removal
|
||||
assertTrue(iter.hasNext());
|
||||
assertEquals('b',iter.next().charValue());
|
||||
assertEquals('c',iter.next().charValue());
|
||||
assertFalse(iter.hasNext());
|
||||
}
|
||||
|
||||
/**
|
||||
* tests the Collections.sort method because that is used
|
||||
* in the router and internally creates iterators
|
||||
*/
|
||||
@Test
|
||||
public void testSorting() {
|
||||
List<Integer> li = new CachedIteratorArrayList<Integer>();
|
||||
li.add(3);
|
||||
li.add(2);
|
||||
li.add(1);
|
||||
Collections.sort(li);
|
||||
|
||||
Iterator<Integer> ii = li.iterator();
|
||||
assertEquals(1,ii.next().intValue());
|
||||
assertEquals(2,ii.next().intValue());
|
||||
assertEquals(3,ii.next().intValue());
|
||||
|
||||
assertFalse(ii.hasNext());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user