implement Iterator in Inlist.List

+ reverse(), append()
This commit is contained in:
Hannes Janetzek 2014-03-25 17:16:12 +01:00
parent dfe6ca99ce
commit 6d9b62af72
3 changed files with 195 additions and 43 deletions

View 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;
}
};
}

View File

@ -82,7 +82,7 @@ public final class SymbolLayer extends TextureLayer {
textures = null;
TextureItem t = null;
for (SymbolItem it = mSymbols.getHead(); it != null;) {
for (SymbolItem it = mSymbols.head(); it != null;) {
int width = 0, height = 0;
int x = 0;
int y = 0;

View File

@ -29,53 +29,85 @@ import javax.annotation.CheckReturnValue;
* are *REALLY* sure about it. Better do not use it! :)
*/
public class Inlist<T extends Inlist<T>> {
/** UNTESTED */
@SuppressWarnings({ "rawtypes", "unchecked" })
public static class List<T extends Inlist<?>> implements Iterable<T> {
Inlist head;
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;
}
public static class List<T extends Inlist<?>> implements Iterable<T>, Iterator<T> {
private Inlist head;
private Inlist cur;
/**
* Insert single item at start of list.
* item.next must be null.
*/
public void push(T it) {
if (it.next != null)
throw new IllegalArgumentException("item.next must be null");
((Inlist) it).next = head;
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) {
cur = null;
head = Inlist.remove(head, it);
}
/**
* Clear list.
*
* @return head of list
*/
public T clear() {
Inlist ret = head;
head = null;
@ -83,17 +115,46 @@ public class Inlist<T extends Inlist<T>> {
return (T) ret;
}
public T getHead() {
/** @return first node in list */
public 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() {
return next;
}
/**
* Push 'item' onto 'list'.
*
@ -101,9 +162,10 @@ public class Inlist<T extends Inlist<T>> {
* @param item the item
* @return the new head of 'list' (item)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
@CheckReturnValue
public static <T extends Inlist<T>> T push(T list, T item) {
item.next = list;
public static <T extends Inlist<?>> T push(T list, T item) {
((Inlist) (item)).next = list;
return item;
}
@ -215,7 +277,7 @@ public class Inlist<T extends Inlist<T>> {
it.next = other;
break;
} 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;
}
public T next() {
return next;
}
}