implement Iterator in Inlist.List
+ reverse(), append()
This commit is contained in:
parent
dfe6ca99ce
commit
6d9b62af72
86
vtm-tests/test/org/oscim/utils/pool/InlistTest.java
Normal file
86
vtm-tests/test/org/oscim/utils/pool/InlistTest.java
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package org.oscim.utils.pool;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.oscim.utils.pool.Inlist.List;
|
||||||
|
|
||||||
|
public class InlistTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldWork() {
|
||||||
|
List<Thing> list = new List<Thing>();
|
||||||
|
|
||||||
|
list.reverse();
|
||||||
|
assertNull(list.pop());
|
||||||
|
|
||||||
|
list.push(new Thing(1));
|
||||||
|
list.push(new Thing(2));
|
||||||
|
list.push(new Thing(3));
|
||||||
|
list.push(new Thing(4));
|
||||||
|
list.push(new Thing(5));
|
||||||
|
|
||||||
|
/* iterate items */
|
||||||
|
int i = 5;
|
||||||
|
for (Thing it : list)
|
||||||
|
assertEquals(it.value, i--);
|
||||||
|
|
||||||
|
assertEquals(i, 0);
|
||||||
|
|
||||||
|
/* iterate with insertion order */
|
||||||
|
list.reverse();
|
||||||
|
i = 1;
|
||||||
|
for (Thing it : list)
|
||||||
|
assertEquals(it.value, i++);
|
||||||
|
|
||||||
|
assertEquals(i, 6);
|
||||||
|
|
||||||
|
list.reverse();
|
||||||
|
|
||||||
|
List<Thing> list2 = new List<Thing>();
|
||||||
|
|
||||||
|
/* pop list and append to list2 */
|
||||||
|
for (int j = 5; j > 0; j--) {
|
||||||
|
Thing t = list.pop();
|
||||||
|
assertEquals(t.value, j);
|
||||||
|
Assert.assertNull(t.next);
|
||||||
|
|
||||||
|
list2.append(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check nothing to iterate */
|
||||||
|
for (Thing t : list)
|
||||||
|
assert (t == null && t != null);
|
||||||
|
|
||||||
|
assertNull(list.pop());
|
||||||
|
assertNull(list.head());
|
||||||
|
|
||||||
|
list.push(new Thing(6));
|
||||||
|
|
||||||
|
/* move items from list2 to list */
|
||||||
|
list.appendList(list2.clear());
|
||||||
|
|
||||||
|
assertNull(list2.head());
|
||||||
|
assertNull(list2.pop());
|
||||||
|
|
||||||
|
list.reverse();
|
||||||
|
|
||||||
|
list.push(new Thing(0));
|
||||||
|
i = 0;
|
||||||
|
for (Thing t : list)
|
||||||
|
assertEquals(t.value, i++);
|
||||||
|
|
||||||
|
assertEquals(i, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Thing extends Inlist<Thing> {
|
||||||
|
final int value;
|
||||||
|
|
||||||
|
public Thing(int val) {
|
||||||
|
value = val;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -82,7 +82,7 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
textures = null;
|
textures = null;
|
||||||
TextureItem t = null;
|
TextureItem t = null;
|
||||||
|
|
||||||
for (SymbolItem it = mSymbols.getHead(); it != null;) {
|
for (SymbolItem it = mSymbols.head(); it != null;) {
|
||||||
int width = 0, height = 0;
|
int width = 0, height = 0;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
|
@ -29,53 +29,85 @@ import javax.annotation.CheckReturnValue;
|
|||||||
* are *REALLY* sure about it. Better do not use it! :)
|
* are *REALLY* sure about it. Better do not use it! :)
|
||||||
*/
|
*/
|
||||||
public class Inlist<T extends Inlist<T>> {
|
public class Inlist<T extends Inlist<T>> {
|
||||||
/** UNTESTED */
|
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
public static class List<T extends Inlist<?>> implements Iterable<T> {
|
public static class List<T extends Inlist<?>> implements Iterable<T>, Iterator<T> {
|
||||||
Inlist head;
|
private Inlist head;
|
||||||
Inlist cur;
|
private Inlist cur;
|
||||||
Iterator<T> mIterator = new Iterator<T>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasNext() {
|
|
||||||
return cur != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T next() {
|
|
||||||
if (cur == null)
|
|
||||||
throw new IllegalStateException();
|
|
||||||
|
|
||||||
Inlist tmp = cur;
|
|
||||||
cur = cur.next;
|
|
||||||
return (T) tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void remove() {
|
|
||||||
T tmp = (T) cur.next;
|
|
||||||
head = Inlist.remove(head, cur);
|
|
||||||
cur = tmp;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<T> iterator() {
|
|
||||||
cur = head;
|
|
||||||
return mIterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert single item at start of list.
|
||||||
|
* item.next must be null.
|
||||||
|
*/
|
||||||
public void push(T it) {
|
public void push(T it) {
|
||||||
|
if (it.next != null)
|
||||||
|
throw new IllegalArgumentException("item.next must be null");
|
||||||
|
|
||||||
((Inlist) it).next = head;
|
((Inlist) it).next = head;
|
||||||
head = it;
|
head = it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert item at start of list.
|
||||||
|
*/
|
||||||
|
public T pop() {
|
||||||
|
if (head == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
Inlist it = head;
|
||||||
|
head = it.next;
|
||||||
|
it.next = null;
|
||||||
|
return (T) it;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse list.
|
||||||
|
*/
|
||||||
|
public void reverse() {
|
||||||
|
Inlist tmp;
|
||||||
|
Inlist itr = head;
|
||||||
|
head = null;
|
||||||
|
|
||||||
|
while (itr != null) {
|
||||||
|
/* keep next */
|
||||||
|
tmp = itr.next;
|
||||||
|
|
||||||
|
/* push itr onto new list */
|
||||||
|
itr.next = head;
|
||||||
|
head = itr;
|
||||||
|
|
||||||
|
itr = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append item, O(n) - use push() and
|
||||||
|
* reverse() to iterate in insertion order!
|
||||||
|
*/
|
||||||
|
public void append(T it) {
|
||||||
|
head = Inlist.appendItem(head, it);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append Inlist.
|
||||||
|
*/
|
||||||
|
public void appendList(T list) {
|
||||||
|
head = Inlist.appendList(head, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove item from list.
|
||||||
|
*/
|
||||||
public void remove(T it) {
|
public void remove(T it) {
|
||||||
cur = null;
|
cur = null;
|
||||||
head = Inlist.remove(head, it);
|
head = Inlist.remove(head, it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear list.
|
||||||
|
*
|
||||||
|
* @return head of list
|
||||||
|
*/
|
||||||
public T clear() {
|
public T clear() {
|
||||||
Inlist ret = head;
|
Inlist ret = head;
|
||||||
head = null;
|
head = null;
|
||||||
@ -83,17 +115,46 @@ public class Inlist<T extends Inlist<T>> {
|
|||||||
return (T) ret;
|
return (T) ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T getHead() {
|
/** @return first node in list */
|
||||||
|
public T head() {
|
||||||
return (T) head;
|
return (T) head;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Iterator: Has next item */
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return cur != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Iterator: Get next item */
|
||||||
|
@Override
|
||||||
|
public T next() {
|
||||||
|
if (cur == null)
|
||||||
|
throw new IllegalStateException();
|
||||||
|
|
||||||
|
Inlist tmp = cur;
|
||||||
|
cur = cur.next;
|
||||||
|
return (T) tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Iterator: Remove current item */
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
T tmp = (T) cur.next;
|
||||||
|
head = Inlist.remove(head, cur);
|
||||||
|
cur = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** NB: Only one iterator at a time possible! */
|
||||||
|
@Override
|
||||||
|
public Iterator<T> iterator() {
|
||||||
|
cur = head;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public T next;
|
public T next;
|
||||||
|
|
||||||
public T next() {
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Push 'item' onto 'list'.
|
* Push 'item' onto 'list'.
|
||||||
*
|
*
|
||||||
@ -101,9 +162,10 @@ public class Inlist<T extends Inlist<T>> {
|
|||||||
* @param item the item
|
* @param item the item
|
||||||
* @return the new head of 'list' (item)
|
* @return the new head of 'list' (item)
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
@CheckReturnValue
|
@CheckReturnValue
|
||||||
public static <T extends Inlist<T>> T push(T list, T item) {
|
public static <T extends Inlist<?>> T push(T list, T item) {
|
||||||
item.next = list;
|
((Inlist) (item)).next = list;
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +277,7 @@ public class Inlist<T extends Inlist<T>> {
|
|||||||
it.next = other;
|
it.next = other;
|
||||||
break;
|
break;
|
||||||
} else if (it.next == other) {
|
} else if (it.next == other) {
|
||||||
throw new IllegalArgumentException("'other' alreay in 'list'");
|
throw new IllegalArgumentException("'other' already in 'list'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,4 +335,8 @@ public class Inlist<T extends Inlist<T>> {
|
|||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T next() {
|
||||||
|
return next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user