876 lines
22 KiB
Plaintext
876 lines
22 KiB
Plaintext
package speiger.src.collections.PACKAGE.lists;
|
|
|
|
import java.util.Collection;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.ListIterator;
|
|
import java.util.NoSuchElementException;
|
|
import java.util.Objects;
|
|
import java.util.RandomAccess;
|
|
|
|
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
|
|
import speiger.src.collections.PACKAGE.collections.COLLECTION;
|
|
import speiger.src.collections.PACKAGE.collections.ITERATOR;
|
|
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
|
|
#if INT_LIST_MODULE && !TYPE_INT
|
|
import speiger.src.collections.ints.lists.IntList;
|
|
#endif
|
|
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
|
|
import speiger.src.collections.utils.SanityChecks;
|
|
|
|
/**
|
|
* Abstract implementation of the {@link LIST} interface.
|
|
* @Type(T)
|
|
*/
|
|
public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE
|
|
{
|
|
/**
|
|
* A Type-Specific implementation of add function that delegates to {@link List#add(int, Object)}
|
|
*/
|
|
@Override
|
|
public boolean add(KEY_TYPE e) {
|
|
add(size(), e);
|
|
return true;
|
|
}
|
|
|
|
#if !TYPE_OBJECT
|
|
/** {@inheritDoc}
|
|
* <p>This default implementation delegates to the corresponding type-specific function.
|
|
* @deprecated Please use the corresponding type-specific function instead.
|
|
*/
|
|
@Override
|
|
@Deprecated
|
|
public void add(int index, CLASS_TYPE element) {
|
|
add(index, OBJ_TO_KEY(element));
|
|
}
|
|
|
|
#endif
|
|
/**
|
|
* A Type-Specific implementation that iterates over the elements and adds them.
|
|
* @param c the elements that wants to be added
|
|
* @return true if the list was modified
|
|
*/
|
|
@Override
|
|
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) {
|
|
return addAll(size(), c);
|
|
}
|
|
|
|
/**
|
|
* A Type-Specific implementation that iterates over the elements and adds them.
|
|
* @param c the elements that wants to be added
|
|
* @return true if the list was modified
|
|
*/
|
|
@Override
|
|
public boolean addAll(LIST KEY_GENERIC_TYPE c) {
|
|
return addAll(size(), c);
|
|
}
|
|
|
|
/** {@inheritDoc}
|
|
* <p>This default implementation delegates to the corresponding type-specific function.
|
|
* @deprecated Please use the corresponding type-specific function instead.
|
|
*/
|
|
@Override
|
|
@Deprecated
|
|
public boolean addAll(Collection<? extends CLASS_TYPE> c) {
|
|
return c instanceof COLLECTION ? addAll((COLLECTION KEY_GENERIC_TYPE)c) : addAll(size(), c);
|
|
}
|
|
|
|
/**
|
|
* The IndexOf implementation iterates over all elements and compares them to the search value.
|
|
* @param o the value that the index is searched for.
|
|
* @return index of the value that was searched for. -1 if not found
|
|
* @note it is highly suggested not to use this with Primitives because of boxing. But it is still supported because of ObjectComparason that are custom objects and allow to find the contents.
|
|
*/
|
|
@Override
|
|
@Primitive
|
|
public int indexOf(Object o) {
|
|
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator();
|
|
#if TYPE_OBJECT
|
|
if(o == null) {
|
|
while(iter.hasNext()) {
|
|
if(iter.NEXT() == null)
|
|
return iter.previousIndex();
|
|
}
|
|
return -1;
|
|
}
|
|
#else
|
|
if(o == null) return -1;
|
|
#endif
|
|
while(iter.hasNext()) {
|
|
if(EQUALS_KEY_TYPE(iter.NEXT(), o))
|
|
return iter.previousIndex();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* The lastIndexOf implementation iterates over all elements and compares them to the search value.
|
|
* @param o the value that the index is searched for.
|
|
* @return the last index of the value that was searched for. -1 if not found
|
|
* @note it is highly suggested not to use this with Primitives because of boxing. But it is still supported because of ObjectComparason that are custom objects and allow to find the contents.
|
|
*/
|
|
@Override
|
|
@Primitive
|
|
public int lastIndexOf(Object o) {
|
|
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator(size());
|
|
#if TYPE_OBJECT
|
|
if(o == null) {
|
|
while(iter.hasPrevious()) {
|
|
if(iter.PREVIOUS() == null)
|
|
return iter.nextIndex();
|
|
}
|
|
return -1;
|
|
}
|
|
#else
|
|
if(o == null) return -1;
|
|
#endif
|
|
while(iter.hasPrevious()) {
|
|
if(EQUALS_KEY_TYPE(iter.PREVIOUS(), o))
|
|
return iter.nextIndex();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
#if !TYPE_OBJECT
|
|
/**
|
|
* The indexOf implementation iterates over all elements and compares them to the search value.
|
|
* @param e the value that the index is searched for.
|
|
* @return index of the value that was searched for. -1 if not found
|
|
*/
|
|
@Override
|
|
public int indexOf(KEY_TYPE e) {
|
|
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator();
|
|
while(iter.hasNext()) {
|
|
if(KEY_EQUALS(iter.NEXT(), e))
|
|
return iter.previousIndex();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* The lastIndexOf implementation iterates over all elements and compares them to the search value.
|
|
* @param e the value that the index is searched for.
|
|
* @return the last index of the value that was searched for. -1 if not found
|
|
*/
|
|
@Override
|
|
public int lastIndexOf(KEY_TYPE e) {
|
|
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator(size());
|
|
while(iter.hasPrevious()) {
|
|
if(KEY_EQUALS(iter.PREVIOUS(), e))
|
|
return iter.nextIndex();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public boolean REMOVE_SWAP(KEY_TYPE e) {
|
|
int index = indexOf(e);
|
|
if(index == -1) return false;
|
|
swapRemove(index);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Compares if the list are the same.
|
|
*/
|
|
@Override
|
|
public boolean equals(Object o) {
|
|
if (o == this)
|
|
return true;
|
|
if (!(o instanceof List))
|
|
return false;
|
|
List<?> l = (List<?>)o;
|
|
if(l.size() != size()) return false;
|
|
#if !TYPE_OBJECT
|
|
if(l instanceof LIST)
|
|
{
|
|
LIST_ITERATOR e1 = listIterator();
|
|
LIST_ITERATOR e2 = ((LIST)l).listIterator();
|
|
while (e1.hasNext() && e2.hasNext()) {
|
|
if(!(KEY_EQUALS(e1.NEXT(), e2.NEXT())))
|
|
return false;
|
|
}
|
|
return !(e1.hasNext() || e2.hasNext());
|
|
}
|
|
#endif
|
|
ListIterator<CLASS_TYPE> e1 = listIterator();
|
|
ListIterator<?> e2 = l.listIterator();
|
|
while (e1.hasNext() && e2.hasNext()) {
|
|
if(!Objects.equals(e1.next(), e2.next()))
|
|
return false;
|
|
}
|
|
return !(e1.hasNext() || e2.hasNext());
|
|
}
|
|
|
|
/**
|
|
* Generates the hashcode based on the values stored in the list.
|
|
*/
|
|
@Override
|
|
public int hashCode() {
|
|
int hashCode = 1;
|
|
LIST_ITERATOR KEY_GENERIC_TYPE i = listIterator();
|
|
while(i.hasNext())
|
|
#if TYPE_OBJECT
|
|
hashCode = 31 * hashCode + i.next().hashCode();
|
|
#else
|
|
hashCode = 31 * hashCode + KEY_TO_HASH(i.NEXT());
|
|
#endif
|
|
return hashCode;
|
|
}
|
|
|
|
@Override
|
|
public LIST KEY_GENERIC_TYPE subList(int fromIndex, int toIndex) {
|
|
SanityChecks.checkArrayCapacity(size(), fromIndex, toIndex-fromIndex);
|
|
return new SubList(this, 0, fromIndex, toIndex);
|
|
}
|
|
|
|
@Override
|
|
public LIST KEY_GENERIC_TYPE reversed() {
|
|
return new ReversedList(this);
|
|
}
|
|
|
|
@Override
|
|
public ITERATOR KEY_GENERIC_TYPE iterator() {
|
|
return listIterator(0);
|
|
}
|
|
|
|
@Override
|
|
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator() {
|
|
return listIterator(0);
|
|
}
|
|
|
|
@Override
|
|
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) {
|
|
if(index < 0 || index > size()) throw new IndexOutOfBoundsException();
|
|
return new LIST_ITER(index);
|
|
}
|
|
|
|
@Override
|
|
public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(int...indecies) {
|
|
return new IndexedIterator(indecies);
|
|
}
|
|
|
|
#if INT_LIST_MODULE
|
|
@Override
|
|
public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(IntList indecies) {
|
|
return new ListIndexedIterator(indecies);
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public void size(int size) {
|
|
while(size > size()) add(EMPTY_KEY_VALUE);
|
|
while(size < size()) REMOVE(size() - 1);
|
|
}
|
|
|
|
public ABSTRACT_LIST KEY_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); }
|
|
|
|
private class ReversedList extends ABSTRACT_LIST KEY_GENERIC_TYPE
|
|
{
|
|
final ABSTRACT_LIST KEY_GENERIC_TYPE list;
|
|
|
|
public ReversedList(ABSTRACT_LIST KEY_GENERIC_TYPE list) {
|
|
this.list = list;
|
|
}
|
|
|
|
@Override
|
|
public void add(int index, KEY_TYPE e) {
|
|
list.add(list.size() - index - 1, e);
|
|
}
|
|
|
|
@Override
|
|
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) {
|
|
return addCollection(index, c);
|
|
}
|
|
|
|
@Override
|
|
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) {
|
|
if(c instanceof RandomAccess) {
|
|
for(int i = 0,m=c.size();i<m;i++) {
|
|
list.add(list.size() - index - i - 1, c.GET_KEY(i));
|
|
}
|
|
return true;
|
|
}
|
|
return addCollection(index, c);
|
|
}
|
|
|
|
private boolean addCollection(int index, COLLECTION KEY_GENERIC_TYPE c) {
|
|
int i = 0;
|
|
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();i++) {
|
|
list.add(list.size() - index - i - 1, iter.NEXT());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) {
|
|
int i = 0;
|
|
for(Iterator<? extends CLASS_TYPE> iter = c.iterator();iter.hasNext();i++) {
|
|
list.add(list.size() - index - i - 1, iter.next());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE GET_KEY(int index) {
|
|
return list.GET_KEY(list.size() - index - 1);
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE set(int index, KEY_TYPE e) {
|
|
return list.set(list.size() - index - 1, e);
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE REMOVE(int index) {
|
|
return list.REMOVE(list.size() - index - 1);
|
|
}
|
|
|
|
@Override
|
|
public void addElements(int from, KEY_TYPE[] a, int offset, int length) {
|
|
for(int i = 0,m=length;i<m;i++) {
|
|
list.add(list.size() - from - i - 1, a[i+offset]);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) {
|
|
return reverse(list.getElements(list.size() - from - 1, a, offset, length));
|
|
}
|
|
|
|
@Override
|
|
public void removeElements(int from, int to) {
|
|
list.removeElements(list.size() - to - 1, list.size() - from - 1);
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE swapRemove(int index) {
|
|
return list.swapRemove(list.size() - index - 1);
|
|
}
|
|
#if TYPE_OBJECT
|
|
@Override
|
|
public <K> K[] extractElements(int from, int to, Class<K> type) {
|
|
return reverse(list.extractElements(list.size() - to - 1, list.size() - from - 1, type));
|
|
}
|
|
|
|
#else
|
|
@Override
|
|
public KEY_TYPE[] extractElements(int from, int to) {
|
|
return reverse(list.extractElements(list.size() - to - 1, list.size() - from - 1));
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public int size() {
|
|
return list.size();
|
|
}
|
|
|
|
@Override
|
|
public void clear() {
|
|
list.clear();
|
|
}
|
|
|
|
@Override
|
|
public LIST KEY_GENERIC_TYPE reversed() {
|
|
return list;
|
|
}
|
|
|
|
#if TYPE_OBJECT
|
|
private <K> K[] reverse(K[] data) {
|
|
for (int i = 0, mid = data.length >> 1, j = data.length - 1; i < mid; i++, j--) {
|
|
K t = data[i];
|
|
data[i] = data[j];
|
|
data[j] = t;
|
|
}
|
|
return data;
|
|
}
|
|
#else
|
|
private KEY_TYPE[] reverse(KEY_TYPE[] data) {
|
|
for (int i = 0, mid = data.length >> 1, j = data.length - 1; i < mid; i++, j--) {
|
|
KEY_TYPE t = data[i];
|
|
data[i] = data[j];
|
|
data[j] = t;
|
|
}
|
|
return data;
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
private class SubList extends ABSTRACT_LIST KEY_GENERIC_TYPE
|
|
{
|
|
final ABSTRACT_LIST KEY_GENERIC_TYPE list;
|
|
final int parentOffset;
|
|
final int offset;
|
|
int size;
|
|
|
|
public SubList(ABSTRACT_LIST KEY_GENERIC_TYPE list, int offset, int from, int to) {
|
|
this.list = list;
|
|
this.parentOffset = from;
|
|
this.offset = offset + from;
|
|
this.size = to - from;
|
|
}
|
|
|
|
@Override
|
|
public void add(int index, KEY_TYPE element) {
|
|
checkAddSubRange(index);
|
|
list.add(parentOffset+index, element);
|
|
size++;
|
|
}
|
|
|
|
@Override
|
|
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) {
|
|
checkAddSubRange(index);
|
|
int add = c.size();
|
|
if(add <= 0) return false;
|
|
list.addAll(parentOffset+index, c);
|
|
this.size += add;
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) {
|
|
checkAddSubRange(index);
|
|
int add = c.size();
|
|
if(add <= 0) return false;
|
|
list.addAll(parentOffset+index, c);
|
|
this.size += add;
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) {
|
|
checkAddSubRange(index);
|
|
int add = c.size();
|
|
if(add <= 0) return false;
|
|
list.addAll(parentOffset+index, c);
|
|
this.size += add;
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void addElements(int from, KEY_TYPE[] a, int offset, int length) {
|
|
checkAddSubRange(from);
|
|
if(length <= 0) return;
|
|
list.addElements(parentOffset+from, a, offset, length);
|
|
this.size += length;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) {
|
|
SanityChecks.checkArrayCapacity(size, from, length);
|
|
SanityChecks.checkArrayCapacity(a.length, offset, length);
|
|
return list.getElements(from+parentOffset, a, offset, length);
|
|
}
|
|
|
|
@Override
|
|
public void removeElements(int from, int to) {
|
|
if(to-from <= 0) return;
|
|
checkSubRange(from);
|
|
checkAddSubRange(to);
|
|
list.removeElements(from+parentOffset, to+parentOffset);
|
|
size -= to - from;
|
|
}
|
|
|
|
#if TYPE_OBJECT
|
|
@Override
|
|
public <K> K[] extractElements(int from, int to, Class<K> type) {
|
|
checkSubRange(from);
|
|
checkAddSubRange(to);
|
|
K[] result = list.extractElements(from+parentOffset, to+parentOffset, type);
|
|
size -= result.length;
|
|
return result;
|
|
}
|
|
|
|
#else
|
|
@Override
|
|
public KEY_TYPE[] extractElements(int from, int to) {
|
|
checkSubRange(from);
|
|
checkAddSubRange(to);
|
|
KEY_TYPE[] result = list.extractElements(from+parentOffset, to+parentOffset);
|
|
size -= result.length;
|
|
return result;
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public KEY_TYPE GET_KEY(int index) {
|
|
checkSubRange(index);
|
|
return list.GET_KEY(parentOffset+index);
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE set(int index, KEY_TYPE element) {
|
|
checkSubRange(index);
|
|
return list.set(parentOffset+index, element);
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE swapRemove(int index) {
|
|
checkSubRange(index);
|
|
if(index == size-1) {
|
|
KEY_TYPE result = list.REMOVE(parentOffset+size-1);
|
|
size--;
|
|
return result;
|
|
}
|
|
KEY_TYPE result = list.set(index+parentOffset, list.GET_KEY(parentOffset+size-1));
|
|
list.REMOVE(parentOffset+size-1);
|
|
size--;
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE REMOVE(int index) {
|
|
checkSubRange(index);
|
|
KEY_TYPE result = list.REMOVE(index+parentOffset);
|
|
size--;
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public int size() {
|
|
return size;
|
|
}
|
|
|
|
@Override
|
|
public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 16464); }
|
|
|
|
@Override
|
|
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) {
|
|
if(index < 0 || index > size()) throw new IndexOutOfBoundsException();
|
|
return new SubListIterator(this, index);
|
|
}
|
|
|
|
@Override
|
|
public LIST KEY_GENERIC_TYPE subList(int fromIndex, int toIndex) {
|
|
SanityChecks.checkArrayCapacity(size, fromIndex, toIndex-fromIndex);
|
|
return new SubList(this, offset, fromIndex, toIndex);
|
|
}
|
|
|
|
protected void checkSubRange(int index) {
|
|
if (index < 0 || index >= size)
|
|
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
|
|
}
|
|
|
|
protected void checkAddSubRange(int index) {
|
|
if (index < 0 || index > size)
|
|
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
|
|
}
|
|
|
|
private class SubListIterator implements LIST_ITERATOR KEY_GENERIC_TYPE
|
|
{
|
|
ABSTRACT_LIST KEY_GENERIC_TYPE list;
|
|
int index;
|
|
int lastReturned = -1;
|
|
|
|
SubListIterator(ABSTRACT_LIST KEY_GENERIC_TYPE list, int index) {
|
|
this.list = list;
|
|
this.index = index;
|
|
}
|
|
|
|
@Override
|
|
public boolean hasNext() {
|
|
return index < list.size();
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE NEXT() {
|
|
if(!hasNext()) throw new NoSuchElementException();
|
|
int i = index++;
|
|
return list.GET_KEY((lastReturned = i));
|
|
}
|
|
|
|
@Override
|
|
public boolean hasPrevious() {
|
|
return index > 0;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE PREVIOUS() {
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
|
index--;
|
|
return list.GET_KEY((lastReturned = index));
|
|
}
|
|
|
|
@Override
|
|
public int nextIndex() {
|
|
return index;
|
|
}
|
|
|
|
@Override
|
|
public int previousIndex() {
|
|
return index-1;
|
|
}
|
|
|
|
@Override
|
|
public void remove() {
|
|
if(lastReturned == -1) throw new IllegalStateException();
|
|
list.REMOVE(lastReturned);
|
|
index = lastReturned;
|
|
lastReturned = -1;
|
|
}
|
|
|
|
@Override
|
|
public void set(KEY_TYPE e) {
|
|
if(lastReturned == -1) throw new IllegalStateException();
|
|
list.set(lastReturned, e);
|
|
}
|
|
|
|
@Override
|
|
public void add(KEY_TYPE e) {
|
|
list.add(index, e);
|
|
index++;
|
|
lastReturned = -1;
|
|
}
|
|
|
|
@Override
|
|
public int skip(int amount) {
|
|
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
|
int steps = Math.min(amount, size() - index);
|
|
index += steps;
|
|
if(steps > 0) lastReturned = Math.min(index-1, size()-1);
|
|
return steps;
|
|
}
|
|
|
|
@Override
|
|
public int back(int amount) {
|
|
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
|
int steps = Math.min(amount, index);
|
|
index -= steps;
|
|
if(steps > 0) lastReturned = Math.min(index, size()-1);
|
|
return steps;
|
|
}
|
|
}
|
|
}
|
|
|
|
#if INT_LIST_MODULE
|
|
private class ListIndexedIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
|
|
IntList indecies;
|
|
int index;
|
|
int lastReturned = -1;
|
|
|
|
ListIndexedIterator(IntList indecies) {
|
|
this.indecies = indecies;
|
|
}
|
|
|
|
@Override
|
|
public boolean hasNext() {
|
|
return index < indecies.size();
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE NEXT() {
|
|
if(!hasNext()) throw new NoSuchElementException();
|
|
int i = index++;
|
|
return GET_KEY((lastReturned = indecies.getInt(i)));
|
|
}
|
|
|
|
@Override
|
|
public boolean hasPrevious() {
|
|
return index > 0;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE PREVIOUS() {
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
|
index--;
|
|
return GET_KEY((lastReturned = indecies.getInt(index)));
|
|
}
|
|
|
|
@Override
|
|
public int nextIndex() {
|
|
return index;
|
|
}
|
|
|
|
@Override
|
|
public int previousIndex() {
|
|
return index-1;
|
|
}
|
|
|
|
@Override
|
|
public void remove() { throw new UnsupportedOperationException(); }
|
|
@Override
|
|
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
|
|
|
|
@Override
|
|
public void set(KEY_TYPE e) {
|
|
if(lastReturned == -1) throw new IllegalStateException();
|
|
ABSTRACT_LIST.this.set(lastReturned, e);
|
|
}
|
|
|
|
@Override
|
|
public int skip(int amount) {
|
|
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
|
int steps = Math.min(amount, indecies.size() - index);
|
|
index += steps;
|
|
if(steps > 0) lastReturned = Math.min(index-1, indecies.size()-1);
|
|
return steps;
|
|
}
|
|
|
|
@Override
|
|
public int back(int amount) {
|
|
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
|
int steps = Math.min(amount, index);
|
|
index -= steps;
|
|
if(steps > 0) lastReturned = Math.max(index, 0);
|
|
return steps;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
private class IndexedIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
|
|
int[] indecies;
|
|
int index;
|
|
int lastReturned = -1;
|
|
|
|
IndexedIterator(int[] indecies) {
|
|
this.indecies = indecies;
|
|
}
|
|
|
|
@Override
|
|
public boolean hasNext() {
|
|
return index < indecies.length;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE NEXT() {
|
|
if(!hasNext()) throw new NoSuchElementException();
|
|
int i = index++;
|
|
return GET_KEY((lastReturned = indecies[i]));
|
|
}
|
|
|
|
@Override
|
|
public boolean hasPrevious() {
|
|
return index > 0;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE PREVIOUS() {
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
|
index--;
|
|
return GET_KEY((lastReturned = indecies[index]));
|
|
}
|
|
|
|
@Override
|
|
public int nextIndex() {
|
|
return index;
|
|
}
|
|
|
|
@Override
|
|
public int previousIndex() {
|
|
return index-1;
|
|
}
|
|
|
|
@Override
|
|
public void remove() { throw new UnsupportedOperationException(); }
|
|
@Override
|
|
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
|
|
|
|
@Override
|
|
public void set(KEY_TYPE e) {
|
|
if(lastReturned == -1) throw new IllegalStateException();
|
|
ABSTRACT_LIST.this.set(lastReturned, e);
|
|
}
|
|
|
|
@Override
|
|
public int skip(int amount) {
|
|
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
|
int steps = Math.min(amount, indecies.length - index);
|
|
index += steps;
|
|
if(steps > 0) lastReturned = Math.min(index-1, indecies.length-1);
|
|
return steps;
|
|
}
|
|
|
|
@Override
|
|
public int back(int amount) {
|
|
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
|
int steps = Math.min(amount, index);
|
|
index -= steps;
|
|
if(steps > 0) lastReturned = Math.max(index, 0);
|
|
return steps;
|
|
}
|
|
}
|
|
|
|
private class LIST_ITER implements LIST_ITERATOR KEY_GENERIC_TYPE {
|
|
int index;
|
|
int lastReturned = -1;
|
|
|
|
LIST_ITER(int index) {
|
|
this.index = index;
|
|
}
|
|
|
|
@Override
|
|
public boolean hasNext() {
|
|
return index < size();
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE NEXT() {
|
|
if(!hasNext()) throw new NoSuchElementException();
|
|
int i = index++;
|
|
return GET_KEY((lastReturned = i));
|
|
}
|
|
|
|
@Override
|
|
public boolean hasPrevious() {
|
|
return index > 0;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE PREVIOUS() {
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
|
index--;
|
|
return GET_KEY((lastReturned = index));
|
|
}
|
|
|
|
@Override
|
|
public int nextIndex() {
|
|
return index;
|
|
}
|
|
|
|
@Override
|
|
public int previousIndex() {
|
|
return index-1;
|
|
}
|
|
|
|
@Override
|
|
public void remove() {
|
|
if(lastReturned == -1) throw new IllegalStateException();
|
|
ABSTRACT_LIST.this.REMOVE(lastReturned);
|
|
index = lastReturned;
|
|
lastReturned = -1;
|
|
}
|
|
|
|
@Override
|
|
public void set(KEY_TYPE e) {
|
|
if(lastReturned == -1) throw new IllegalStateException();
|
|
ABSTRACT_LIST.this.set(lastReturned, e);
|
|
}
|
|
|
|
@Override
|
|
public void add(KEY_TYPE e) {
|
|
ABSTRACT_LIST.this.add(index, e);
|
|
index++;
|
|
lastReturned = -1;
|
|
}
|
|
|
|
@Override
|
|
public int skip(int amount) {
|
|
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
|
int steps = Math.min(amount, size() - index);
|
|
index += steps;
|
|
if(steps > 0) lastReturned = Math.min(index-1, size()-1);
|
|
return steps;
|
|
}
|
|
|
|
@Override
|
|
public int back(int amount) {
|
|
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
|
int steps = Math.min(amount, index);
|
|
index -= steps;
|
|
if(steps > 0) lastReturned = Math.max(index, 0);
|
|
return steps;
|
|
}
|
|
}
|
|
} |