2020-12-13 23:41:09 +01:00
|
|
|
package speiger.src.collections.PACKAGE.sets;
|
|
|
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Collection;
|
|
|
|
#if TYPE_OBJECT
|
|
|
|
import java.util.Comparator;
|
2021-01-28 20:42:29 +01:00
|
|
|
import java.util.function.Consumer;
|
2021-10-29 16:03:39 +02:00
|
|
|
import java.util.function.BiFunction;
|
2021-01-07 15:14:51 +01:00
|
|
|
#endif
|
2020-12-13 23:41:09 +01:00
|
|
|
import java.util.NoSuchElementException;
|
|
|
|
import java.util.Objects;
|
|
|
|
import java.util.Set;
|
2021-01-28 20:42:29 +01:00
|
|
|
#if PRIMITIVES
|
|
|
|
import java.util.function.JAVA_PREDICATE;
|
|
|
|
#endif
|
2020-12-13 23:41:09 +01:00
|
|
|
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
|
|
|
|
import speiger.src.collections.PACKAGE.collections.COLLECTION;
|
2021-04-26 22:25:09 +02:00
|
|
|
import speiger.src.collections.PACKAGE.collections.ITERATOR;
|
2021-09-16 02:57:09 +02:00
|
|
|
|
2021-09-28 03:23:21 +02:00
|
|
|
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
|
2021-09-16 02:57:09 +02:00
|
|
|
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
|
2021-10-27 14:09:19 +02:00
|
|
|
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
|
2020-12-13 23:41:09 +01:00
|
|
|
#if !TYPE_OBJECT
|
|
|
|
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
|
2021-01-28 20:42:29 +01:00
|
|
|
import speiger.src.collections.PACKAGE.functions.CONSUMER;
|
2021-05-28 20:08:04 +02:00
|
|
|
import speiger.src.collections.objects.utils.ObjectArrays;
|
2020-12-13 23:41:09 +01:00
|
|
|
#endif
|
|
|
|
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
|
|
|
|
import speiger.src.collections.PACKAGE.utils.ARRAYS;
|
|
|
|
|
2021-05-28 20:08:04 +02:00
|
|
|
|
2021-04-26 22:25:09 +02:00
|
|
|
/**
|
|
|
|
* A Type Specific ArraySet implementation.
|
|
|
|
* That is based around the idea of {@link java.util.List#indexOf(Object)} for no duplication.
|
|
|
|
* Unless a array constructor is used the ArraySet does not allow for duplication.
|
|
|
|
* This implementation does not shrink the backing array
|
|
|
|
* @Type(T)
|
|
|
|
*/
|
2020-12-13 23:41:09 +01:00
|
|
|
public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE
|
|
|
|
{
|
2021-04-26 22:25:09 +02:00
|
|
|
/** The Backing Array */
|
2020-12-13 23:41:09 +01:00
|
|
|
protected transient KEY_TYPE[] data;
|
2021-04-26 22:25:09 +02:00
|
|
|
/** The amount of elements stored in the array*/
|
2020-12-13 23:41:09 +01:00
|
|
|
protected int size = 0;
|
|
|
|
|
2021-04-26 22:25:09 +02:00
|
|
|
/**
|
|
|
|
* Default Constructor
|
|
|
|
*/
|
2020-12-13 23:41:09 +01:00
|
|
|
public ARRAY_SET() {
|
2021-01-20 04:29:08 +01:00
|
|
|
data = EMPTY_KEY_ARRAY;
|
2020-12-13 23:41:09 +01:00
|
|
|
}
|
|
|
|
|
2021-04-26 22:25:09 +02:00
|
|
|
/**
|
|
|
|
* Minimum Capacity Constructor
|
|
|
|
* @param capacity the minimum capacity of the internal array
|
|
|
|
* @throws NegativeArraySizeException if the capacity is negative
|
|
|
|
*/
|
2020-12-13 23:41:09 +01:00
|
|
|
public ARRAY_SET(int capacity) {
|
2021-01-08 21:12:20 +01:00
|
|
|
data = NEW_KEY_ARRAY(capacity);
|
2020-12-13 23:41:09 +01:00
|
|
|
}
|
|
|
|
|
2021-04-26 22:25:09 +02:00
|
|
|
/**
|
|
|
|
* Constructur using initial Array
|
|
|
|
* @param array the array that should be used for set.
|
|
|
|
*/
|
2020-12-13 23:41:09 +01:00
|
|
|
public ARRAY_SET(KEY_TYPE[] array) {
|
|
|
|
this(array, array.length);
|
|
|
|
}
|
|
|
|
|
2021-04-26 22:25:09 +02:00
|
|
|
/**
|
|
|
|
* Constructur using initial Array
|
|
|
|
* @param array the array that should be used for set.
|
|
|
|
* @param length the amount of elements present within the array
|
|
|
|
* @throws NegativeArraySizeException if the length is negative
|
|
|
|
*/
|
2020-12-13 23:41:09 +01:00
|
|
|
public ARRAY_SET(KEY_TYPE[] array, int length) {
|
2021-12-11 12:53:58 +01:00
|
|
|
this(length);
|
|
|
|
addAll(array, length);
|
2020-12-13 23:41:09 +01:00
|
|
|
}
|
|
|
|
|
2021-04-26 22:25:09 +02:00
|
|
|
/**
|
|
|
|
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
|
|
|
|
* @param c the elements that should be added to the set.
|
|
|
|
* @note this slowly checks every element to remove duplicates
|
|
|
|
*/
|
2021-09-02 13:38:25 +02:00
|
|
|
@Primitive
|
2020-12-13 23:41:09 +01:00
|
|
|
public ARRAY_SET(Collection<? extends CLASS_TYPE> c) {
|
|
|
|
this(c.size());
|
|
|
|
addAll(c);
|
|
|
|
}
|
|
|
|
|
2021-04-26 22:25:09 +02:00
|
|
|
/**
|
|
|
|
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
|
|
|
|
* @param c the elements that should be added to the set.
|
|
|
|
* @note this slowly checks every element to remove duplicates
|
|
|
|
*/
|
2020-12-13 23:41:09 +01:00
|
|
|
public ARRAY_SET(COLLECTION KEY_GENERIC_TYPE c) {
|
|
|
|
this(c.size());
|
|
|
|
addAll(c);
|
|
|
|
}
|
|
|
|
|
2021-04-26 22:25:09 +02:00
|
|
|
/**
|
|
|
|
* A Helper constructor that fast copies the element out of a set into the ArraySet.
|
|
|
|
* Since it is assumed that there is no duplication in the first place
|
|
|
|
* @param s the set the element should be taken from
|
|
|
|
*/
|
2021-09-02 13:38:25 +02:00
|
|
|
@Primitive
|
2020-12-13 23:41:09 +01:00
|
|
|
public ARRAY_SET(Set<? extends CLASS_TYPE> s) {
|
|
|
|
this(s.size());
|
|
|
|
for(CLASS_TYPE e : s)
|
|
|
|
data[size++] = OBJ_TO_KEY(e);
|
|
|
|
}
|
|
|
|
|
2021-04-26 22:25:09 +02:00
|
|
|
/**
|
|
|
|
* A Helper constructor that fast copies the element out of a set into the ArraySet.
|
|
|
|
* Since it is assumed that there is no duplication in the first place
|
|
|
|
* @param s the set the element should be taken from
|
|
|
|
*/
|
2020-12-13 23:41:09 +01:00
|
|
|
public ARRAY_SET(SET KEY_GENERIC_TYPE s) {
|
|
|
|
this(s.size());
|
2021-04-26 22:25:09 +02:00
|
|
|
for(ITERATOR KEY_GENERIC_TYPE iter = s.iterator();iter.hasNext();data[size++] = iter.NEXT());
|
2020-12-13 23:41:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean add(KEY_TYPE o) {
|
|
|
|
int index = findIndex(o);
|
|
|
|
if(index == -1) {
|
|
|
|
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
|
|
|
|
data[size++] = o;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean addAndMoveToFirst(KEY_TYPE o) {
|
|
|
|
int index = findIndex(o);
|
|
|
|
if(index == -1) {
|
|
|
|
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
|
|
|
|
System.arraycopy(data, 0, data, 1, size++);
|
|
|
|
data[0] = o;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if(index != 0) {
|
|
|
|
o = data[index];
|
|
|
|
System.arraycopy(data, 0, data, 1, index);
|
2021-01-08 21:12:20 +01:00
|
|
|
data[0] = o;
|
2020-12-13 23:41:09 +01:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean addAndMoveToLast(KEY_TYPE o) {
|
|
|
|
int index = findIndex(o);
|
|
|
|
if(index == -1) {
|
|
|
|
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
|
|
|
|
data[size++] = o;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if(index != size - 1) {
|
|
|
|
o = data[index];
|
|
|
|
System.arraycopy(data, index+1, data, index, size - index);
|
2021-01-08 21:12:20 +01:00
|
|
|
data[size-1] = o;
|
2020-12-13 23:41:09 +01:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean moveToFirst(KEY_TYPE o) {
|
|
|
|
int index = findIndex(o);
|
|
|
|
if(index > 0) {
|
|
|
|
o = data[index];
|
|
|
|
System.arraycopy(data, 0, data, 1, index);
|
2021-01-08 21:12:20 +01:00
|
|
|
data[0] = o;
|
2020-12-13 23:41:09 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean moveToLast(KEY_TYPE o) {
|
|
|
|
int index = findIndex(o);
|
|
|
|
if(index != -1 && index != size - 1) {
|
|
|
|
o = data[index];
|
2021-01-08 21:12:20 +01:00
|
|
|
System.arraycopy(data, index+1, data, index, size - index - 1);
|
|
|
|
data[size-1] = o;
|
2020-12-13 23:41:09 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if !TYPE_OBJECT
|
|
|
|
@Override
|
|
|
|
public boolean contains(KEY_TYPE e) {
|
|
|
|
return findIndex(e) != -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
@Override
|
|
|
|
public boolean contains(Object e) {
|
2021-01-07 15:14:51 +01:00
|
|
|
return findIndex(e) != -1;
|
2020-12-13 23:41:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE FIRST_KEY() {
|
|
|
|
if(size == 0) throw new NoSuchElementException();
|
|
|
|
return data[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE LAST_KEY() {
|
|
|
|
if(size == 0) throw new NoSuchElementException();
|
|
|
|
return data[size - 1];
|
|
|
|
}
|
|
|
|
|
2021-05-28 22:10:30 +02:00
|
|
|
@Override
|
|
|
|
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) {
|
|
|
|
int j = 0;
|
|
|
|
for(int i = 0;i<size;i++) {
|
|
|
|
if(!c.contains(data[i]))
|
|
|
|
data[j++] = data[i];
|
|
|
|
}
|
|
|
|
boolean result = j != size;
|
|
|
|
#if TYPE_OBJECT
|
|
|
|
Arrays.fill(data, j, size, null);
|
|
|
|
#endif
|
|
|
|
size = j;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2021-10-24 01:11:11 +02:00
|
|
|
@Override
|
|
|
|
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) {
|
|
|
|
int j = 0;
|
|
|
|
for(int i = 0;i<size;i++) {
|
|
|
|
if(!c.contains(data[i])) data[j++] = data[i];
|
|
|
|
else r.accept(data[i]);
|
|
|
|
}
|
|
|
|
boolean result = j != size;
|
|
|
|
#if TYPE_OBJECT
|
|
|
|
Arrays.fill(data, j, size, null);
|
|
|
|
#endif
|
|
|
|
size = j;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2021-05-28 22:10:30 +02:00
|
|
|
@Override
|
|
|
|
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) {
|
|
|
|
int j = 0;
|
|
|
|
for(int i = 0;i<size;i++) {
|
|
|
|
if(c.contains(data[i]))
|
|
|
|
data[j++] = data[i];
|
|
|
|
}
|
|
|
|
boolean result = j != size;
|
|
|
|
#if TYPE_OBJECT
|
|
|
|
Arrays.fill(data, j, size, null);
|
|
|
|
#endif
|
|
|
|
size = j;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2021-10-24 01:11:11 +02:00
|
|
|
@Override
|
|
|
|
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) {
|
|
|
|
int j = 0;
|
|
|
|
for(int i = 0;i<size;i++) {
|
|
|
|
if(c.contains(data[i])) data[j++] = data[i];
|
|
|
|
else r.accept(data[i]);
|
|
|
|
}
|
|
|
|
boolean result = j != size;
|
|
|
|
#if TYPE_OBJECT
|
|
|
|
Arrays.fill(data, j, size, null);
|
|
|
|
#endif
|
|
|
|
size = j;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2021-05-28 22:10:30 +02:00
|
|
|
@Override
|
|
|
|
@Primitive
|
|
|
|
public boolean removeAll(Collection<?> c) {
|
|
|
|
int j = 0;
|
|
|
|
for(int i = 0;i<size;i++) {
|
|
|
|
if(!c.contains(KEY_TO_OBJ(data[i])))
|
|
|
|
data[j++] = data[i];
|
|
|
|
}
|
|
|
|
boolean result = j != size;
|
|
|
|
#if TYPE_OBJECT
|
|
|
|
Arrays.fill(data, j, size, null);
|
|
|
|
#endif
|
|
|
|
size = j;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Primitive
|
|
|
|
public boolean retainAll(Collection<?> c) {
|
|
|
|
int j = 0;
|
|
|
|
for(int i = 0;i<size;i++) {
|
|
|
|
if(c.contains(KEY_TO_OBJ(data[i])))
|
|
|
|
data[j++] = data[i];
|
|
|
|
}
|
|
|
|
boolean result = j != size;
|
|
|
|
#if TYPE_OBJECT
|
|
|
|
Arrays.fill(data, j, size, null);
|
|
|
|
#endif
|
|
|
|
size = j;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2020-12-13 23:41:09 +01:00
|
|
|
#if !TYPE_OBJECT
|
|
|
|
@Override
|
|
|
|
public boolean remove(KEY_TYPE o) {
|
|
|
|
int index = findIndex(o);
|
|
|
|
if(index != -1) {
|
2021-01-08 21:12:20 +01:00
|
|
|
size--;
|
|
|
|
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
|
|
|
|
#if TYPE_OBJECT
|
2021-01-21 21:35:23 +01:00
|
|
|
data[size] = EMPTY_KEY_VALUE;
|
2021-01-08 21:12:20 +01:00
|
|
|
#endif
|
2020-12-13 23:41:09 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
@Override
|
|
|
|
public boolean remove(Object o) {
|
2021-01-07 15:14:51 +01:00
|
|
|
int index = findIndex(o);
|
2020-12-13 23:41:09 +01:00
|
|
|
if(index != -1) {
|
2021-01-08 21:12:20 +01:00
|
|
|
size--;
|
|
|
|
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
|
|
|
|
#if TYPE_OBJECT
|
2021-01-21 21:35:23 +01:00
|
|
|
data[size] = EMPTY_KEY_VALUE;
|
2021-01-08 21:12:20 +01:00
|
|
|
#endif
|
2020-12-13 23:41:09 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE POLL_FIRST_KEY() {
|
|
|
|
if(size == 0) throw new NoSuchElementException();
|
|
|
|
KEY_TYPE result = data[0];
|
2021-01-28 20:42:29 +01:00
|
|
|
System.arraycopy(data, 1, data, 0, --size);
|
2020-12-13 23:41:09 +01:00
|
|
|
#if TYPE_OBJECT
|
2021-01-28 20:42:29 +01:00
|
|
|
data[size] = EMPTY_KEY_VALUE;
|
2020-12-13 23:41:09 +01:00
|
|
|
#endif
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE POLL_LAST_KEY() {
|
|
|
|
if(size == 0) throw new NoSuchElementException();
|
2021-01-08 21:12:20 +01:00
|
|
|
size--;
|
2020-12-13 23:41:09 +01:00
|
|
|
#if TYPE_OBJECT
|
2021-01-08 21:12:20 +01:00
|
|
|
KEY_TYPE result = data[size];
|
2021-01-21 21:35:23 +01:00
|
|
|
data[size] = EMPTY_KEY_VALUE;
|
2020-12-13 23:41:09 +01:00
|
|
|
return result;
|
|
|
|
#else
|
2021-01-08 21:12:20 +01:00
|
|
|
return data[size];
|
2020-12-13 23:41:09 +01:00
|
|
|
#endif
|
|
|
|
}
|
2021-01-28 20:42:29 +01:00
|
|
|
#if PRIMITIVES
|
|
|
|
@Override
|
|
|
|
public boolean remIf(JAVA_PREDICATE KEY_GENERIC_TYPE filter) {
|
|
|
|
Objects.requireNonNull(filter);
|
|
|
|
boolean modified = false;
|
|
|
|
int j = 0;
|
2021-01-29 11:41:48 +01:00
|
|
|
for(int i = 0;i<size;i++) {
|
2021-01-28 20:42:29 +01:00
|
|
|
if(!filter.test(data[i])) data[j++] = data[i];
|
|
|
|
else modified = true;
|
|
|
|
}
|
|
|
|
size = j;
|
|
|
|
return modified;
|
|
|
|
}
|
2020-12-13 23:41:09 +01:00
|
|
|
|
2021-01-28 20:42:29 +01:00
|
|
|
#endif
|
|
|
|
@Override
|
2021-09-16 02:57:09 +02:00
|
|
|
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
|
2021-01-28 20:42:29 +01:00
|
|
|
Objects.requireNonNull(action);
|
|
|
|
for(int i = 0;i<size;action.accept(data[i++]));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-09-28 03:23:21 +02:00
|
|
|
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
|
2021-01-28 20:42:29 +01:00
|
|
|
Objects.requireNonNull(action);
|
2021-09-16 02:57:09 +02:00
|
|
|
for(int i = 0;i<size;i++)
|
2021-09-28 03:23:21 +02:00
|
|
|
action.accept(input, data[i]);
|
2021-09-16 02:57:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
|
|
|
|
Objects.requireNonNull(filter);
|
|
|
|
for(int i = 0;i<size;i++) {
|
|
|
|
if(filter.TEST_VALUE(data[i])) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
|
|
|
|
Objects.requireNonNull(filter);
|
|
|
|
for(int i = 0;i<size;i++) {
|
|
|
|
if(filter.TEST_VALUE(data[i])) return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
|
|
|
|
Objects.requireNonNull(filter);
|
|
|
|
for(int i = 0;i<size;i++) {
|
|
|
|
if(!filter.TEST_VALUE(data[i])) return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
|
|
|
|
Objects.requireNonNull(filter);
|
|
|
|
for(int i = 0;i<size;i++) {
|
|
|
|
if(filter.TEST_VALUE(data[i])) return data[i];
|
|
|
|
}
|
|
|
|
return EMPTY_VALUE;
|
2021-01-28 20:42:29 +01:00
|
|
|
}
|
|
|
|
|
2021-10-29 16:03:39 +02:00
|
|
|
#if !TYPE_OBJECT
|
2021-09-28 13:20:05 +02:00
|
|
|
@Override
|
2021-10-27 14:09:19 +02:00
|
|
|
public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
|
|
|
|
Objects.requireNonNull(operator);
|
|
|
|
KEY_TYPE state = identity;
|
|
|
|
for(int i = 0;i<size;i++) {
|
|
|
|
state = operator.APPLY_VALUE(state, data[i]);
|
|
|
|
}
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2021-10-29 16:03:39 +02:00
|
|
|
#else
|
|
|
|
@Override
|
|
|
|
public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) {
|
|
|
|
Objects.requireNonNull(operator);
|
|
|
|
KEY_SPECIAL_TYPE state = identity;
|
|
|
|
for(int i = 0;i<size;i++) {
|
|
|
|
state = operator.APPLY_VALUE(state, data[i]);
|
|
|
|
}
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
2021-10-27 14:09:19 +02:00
|
|
|
@Override
|
|
|
|
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
|
|
|
|
Objects.requireNonNull(operator);
|
|
|
|
KEY_TYPE state = EMPTY_VALUE;
|
|
|
|
boolean empty = true;
|
|
|
|
for(int i = 0;i<size;i++) {
|
|
|
|
if(empty) {
|
|
|
|
empty = false;
|
|
|
|
state = data[i];
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
state = operator.APPLY_VALUE(state, data[i]);
|
|
|
|
}
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-09-28 13:20:05 +02:00
|
|
|
public int count(PREDICATE KEY_GENERIC_TYPE filter) {
|
|
|
|
Objects.requireNonNull(filter);
|
|
|
|
int result = 0;
|
|
|
|
for(int i = 0;i<size;i++) {
|
|
|
|
if(filter.TEST_VALUE(data[i])) result++;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2021-01-07 15:14:51 +01:00
|
|
|
#if !TYPE_OBJECT
|
2020-12-13 23:41:09 +01:00
|
|
|
protected int findIndex(KEY_TYPE o) {
|
|
|
|
for(int i = size-1;i>=0;i--)
|
2021-01-21 21:35:23 +01:00
|
|
|
if(KEY_EQUALS(data[i], o)) return i;
|
2020-12-13 23:41:09 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2021-01-07 15:14:51 +01:00
|
|
|
#endif
|
|
|
|
protected int findIndex(Object o) {
|
|
|
|
for(int i = size-1;i>=0;i--)
|
|
|
|
if(EQUALS_KEY_TYPE(data[i], o)) return i;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2020-12-13 23:41:09 +01:00
|
|
|
@Override
|
|
|
|
public BI_ITERATOR KEY_GENERIC_TYPE iterator() {
|
|
|
|
return new SetIterator(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
|
|
|
|
int index = findIndex(fromElement);
|
|
|
|
if(index != -1) return new SetIterator(index);
|
|
|
|
throw new NoSuchElementException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) {
|
|
|
|
int fromIndex = findIndex(fromElement);
|
|
|
|
int toIndex = findIndex(toElement);
|
|
|
|
if(fromIndex == -1 || toIndex == -1) throw new NoSuchElementException();
|
2021-01-08 21:12:20 +01:00
|
|
|
return new SubSet(fromIndex, toIndex - fromIndex + 1);
|
2020-12-13 23:41:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) {
|
|
|
|
int toIndex = findIndex(toElement);
|
|
|
|
if(toIndex == -1) throw new NoSuchElementException();
|
2021-01-08 21:12:20 +01:00
|
|
|
return new SubSet(0, toIndex+1);
|
2020-12-13 23:41:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) {
|
|
|
|
int fromIndex = findIndex(fromElement);
|
|
|
|
if(fromIndex == -1) throw new NoSuchElementException();
|
|
|
|
return new SubSet(fromIndex, size - fromIndex);
|
|
|
|
}
|
|
|
|
|
2021-10-06 17:43:46 +02:00
|
|
|
public ARRAY_SET KEY_GENERIC_TYPE copy() {
|
|
|
|
ARRAY_SET KEY_GENERIC_TYPE set = new ARRAY_SETBRACES();
|
|
|
|
set.data = Arrays.copyOf(data, data.length);
|
|
|
|
set.size = size;
|
|
|
|
return set;
|
|
|
|
}
|
|
|
|
|
2020-12-13 23:41:09 +01:00
|
|
|
@Override
|
|
|
|
public COMPARATOR KEY_GENERIC_TYPE comparator() {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void clear() {
|
|
|
|
size = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int size() {
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2021-05-28 20:08:04 +02:00
|
|
|
#if !TYPE_OBJECT
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
|
|
|
|
if(a == null || a.length < size()) return Arrays.copyOf(data, size());
|
|
|
|
System.arraycopy(data, 0, a, 0, size());
|
2021-12-11 12:53:58 +01:00
|
|
|
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
|
2021-05-28 20:08:04 +02:00
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
@Override
|
|
|
|
@Deprecated
|
|
|
|
public Object[] toArray() {
|
|
|
|
Object[] obj = new Object[size()];
|
|
|
|
for(int i = 0;i<size();i++)
|
|
|
|
obj[i] = KEY_TO_OBJ(data[i]);
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Primitive
|
|
|
|
public <E> E[] toArray(E[] a) {
|
|
|
|
if(a == null) a = (E[])new Object[size()];
|
|
|
|
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
|
|
|
|
for(int i = 0;i<size();i++)
|
|
|
|
a[i] = (E)KEY_TO_OBJ(data[i]);
|
2021-12-11 12:53:58 +01:00
|
|
|
if (a.length > size) a[size] = null;
|
2021-05-28 20:08:04 +02:00
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2020-12-13 23:41:09 +01:00
|
|
|
private class SubSet extends ABSTRACT_SET KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE {
|
|
|
|
int offset;
|
|
|
|
int length;
|
|
|
|
|
|
|
|
SubSet(int offset, int length) {
|
|
|
|
this.offset = offset;
|
|
|
|
this.length = length;
|
|
|
|
}
|
2021-01-08 21:12:20 +01:00
|
|
|
|
|
|
|
int end() { return offset+length; }
|
2020-12-13 23:41:09 +01:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean add(KEY_TYPE o) {
|
|
|
|
int index = findIndex(o);
|
2021-01-08 21:12:20 +01:00
|
|
|
if(index == -1) {
|
2020-12-13 23:41:09 +01:00
|
|
|
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
|
2021-01-08 21:12:20 +01:00
|
|
|
if(end() != size) System.arraycopy(data, end(), data, end()+1, size-(offset+length));
|
|
|
|
data[end()] = o;
|
2020-12-13 23:41:09 +01:00
|
|
|
size++;
|
|
|
|
length++;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean addAndMoveToFirst(KEY_TYPE o) {
|
|
|
|
int index = findIndex(o);
|
|
|
|
if(index == -1) {
|
|
|
|
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
|
|
|
|
System.arraycopy(data, offset, data, offset+1, size-offset);
|
|
|
|
data[offset] = o;
|
|
|
|
size++;
|
|
|
|
length++;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if(index != 0) {
|
|
|
|
o = data[index];
|
|
|
|
System.arraycopy(data, offset, data, offset+1, index-offset);
|
|
|
|
data[offset] = o;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean addAndMoveToLast(KEY_TYPE o) {
|
|
|
|
int index = findIndex(o);
|
|
|
|
if(index == -1) {
|
|
|
|
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
|
2021-01-08 21:12:20 +01:00
|
|
|
System.arraycopy(data, end()+1, data, end(), size-end());
|
|
|
|
data[end()] = o;
|
2020-12-13 23:41:09 +01:00
|
|
|
size++;
|
|
|
|
length++;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if(index != 0) {
|
|
|
|
o = data[index];
|
|
|
|
System.arraycopy(data, offset+1, data, offset, index-offset);
|
|
|
|
data[offset+length] = o;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean moveToFirst(KEY_TYPE o) {
|
|
|
|
int index = findIndex(o);
|
2021-01-08 21:12:20 +01:00
|
|
|
if(index > offset) {
|
2020-12-13 23:41:09 +01:00
|
|
|
o = data[index];
|
|
|
|
System.arraycopy(data, offset, data, offset+1, index-offset);
|
|
|
|
data[offset] = o;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean moveToLast(KEY_TYPE o) {
|
|
|
|
int index = findIndex(o);
|
2021-01-08 21:12:20 +01:00
|
|
|
if(index != -1 && index < end()-1) {
|
2020-12-13 23:41:09 +01:00
|
|
|
o = data[index];
|
2021-01-08 21:12:20 +01:00
|
|
|
System.arraycopy(data, index+1, data, index, end()-index-1);
|
|
|
|
data[end()-1] = o;
|
2020-12-13 23:41:09 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if !TYPE_OBJECT
|
|
|
|
@Override
|
|
|
|
public boolean contains(KEY_TYPE e) {
|
|
|
|
return findIndex(e) != -1;
|
|
|
|
}
|
|
|
|
|
2021-01-07 15:14:51 +01:00
|
|
|
#endif
|
2020-12-13 23:41:09 +01:00
|
|
|
@Override
|
|
|
|
public boolean contains(Object e) {
|
2021-01-07 15:14:51 +01:00
|
|
|
return findIndex(e) != -1;
|
2020-12-13 23:41:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE FIRST_KEY() {
|
|
|
|
if(length == 0) throw new NoSuchElementException();
|
|
|
|
return data[offset];
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE LAST_KEY() {
|
|
|
|
if(length == 0) throw new NoSuchElementException();
|
2021-01-08 21:12:20 +01:00
|
|
|
return data[end()-1];
|
2020-12-13 23:41:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#if !TYPE_OBJECT
|
|
|
|
@Override
|
|
|
|
public boolean remove(KEY_TYPE o) {
|
|
|
|
int index = findIndex(o);
|
|
|
|
if(index != -1) {
|
|
|
|
size--;
|
|
|
|
length--;
|
2021-01-08 21:12:20 +01:00
|
|
|
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
|
2020-12-13 23:41:09 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-01-07 15:14:51 +01:00
|
|
|
#endif
|
2020-12-13 23:41:09 +01:00
|
|
|
@Override
|
|
|
|
public boolean remove(Object o) {
|
2021-01-07 15:14:51 +01:00
|
|
|
int index = findIndex(o);
|
2020-12-13 23:41:09 +01:00
|
|
|
if(index != -1) {
|
|
|
|
size--;
|
|
|
|
length--;
|
2021-01-08 21:12:20 +01:00
|
|
|
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
|
|
|
|
#if TYPE_OBJECT
|
2021-01-21 21:35:23 +01:00
|
|
|
data[size] = EMPTY_KEY_VALUE;
|
2021-01-08 21:12:20 +01:00
|
|
|
#endif
|
2020-12-13 23:41:09 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE POLL_FIRST_KEY() {
|
|
|
|
if(length == 0) throw new NoSuchElementException();
|
2021-01-08 21:12:20 +01:00
|
|
|
size--;
|
|
|
|
length--;
|
2020-12-13 23:41:09 +01:00
|
|
|
KEY_TYPE result = data[offset];
|
|
|
|
System.arraycopy(data, offset+1, data, offset, size-offset);
|
|
|
|
#if TYPE_OBJECT
|
2021-01-21 21:35:23 +01:00
|
|
|
data[size] = EMPTY_KEY_VALUE;
|
2020-12-13 23:41:09 +01:00
|
|
|
#endif
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE POLL_LAST_KEY() {
|
|
|
|
if(length == 0) throw new NoSuchElementException();
|
|
|
|
KEY_TYPE result = data[offset+length];
|
|
|
|
size--;
|
|
|
|
length--;
|
2021-01-08 21:12:20 +01:00
|
|
|
System.arraycopy(data, end()+1, data, end(), size-end());
|
|
|
|
#if TYPE_OBJECT
|
2021-01-21 21:35:23 +01:00
|
|
|
data[size] = EMPTY_KEY_VALUE;
|
2021-01-08 21:12:20 +01:00
|
|
|
#endif
|
2020-12-13 23:41:09 +01:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public COMPARATOR KEY_GENERIC_TYPE comparator() {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public BI_ITERATOR KEY_GENERIC_TYPE iterator() {
|
|
|
|
return new SetIterator(offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
|
|
|
|
int index = findIndex(fromElement);
|
|
|
|
if(index != -1) return new SetIterator(index);
|
|
|
|
throw new NoSuchElementException();
|
|
|
|
}
|
2021-10-06 17:43:46 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public SubSet copy() { throw new UnsupportedOperationException(); }
|
|
|
|
|
2020-12-13 23:41:09 +01:00
|
|
|
@Override
|
|
|
|
public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) {
|
|
|
|
int fromIndex = findIndex(fromElement);
|
|
|
|
int toIndex = findIndex(toElement);
|
|
|
|
if(fromIndex == -1 || toIndex == -1) throw new NoSuchElementException();
|
2021-05-28 20:08:04 +02:00
|
|
|
return new SubSet(fromIndex, toIndex - fromIndex + 1);
|
2020-12-13 23:41:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) {
|
|
|
|
int toIndex = findIndex(toElement);
|
|
|
|
if(toIndex == -1) throw new NoSuchElementException();
|
2021-05-28 20:08:04 +02:00
|
|
|
return new SubSet(0, toIndex+1);
|
2020-12-13 23:41:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) {
|
|
|
|
int fromIndex = findIndex(fromElement);
|
|
|
|
if(fromIndex == -1) throw new NoSuchElementException();
|
|
|
|
return new SubSet(fromIndex, size - fromIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int size() {
|
|
|
|
return length;
|
|
|
|
}
|
|
|
|
|
2021-05-28 20:08:04 +02:00
|
|
|
#if !TYPE_OBJECT
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
|
|
|
|
if(a == null || a.length < size()) return Arrays.copyOfRange(data, offset, end());
|
|
|
|
System.arraycopy(data, offset, a, 0, size());
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
@Override
|
|
|
|
@Deprecated
|
|
|
|
public Object[] toArray() {
|
|
|
|
Object[] obj = new Object[size()];
|
|
|
|
for(int i = 0;i<size();i++)
|
|
|
|
obj[i] = KEY_TO_OBJ(data[offset+i]);
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Primitive
|
|
|
|
public <E> E[] toArray(E[] a) {
|
|
|
|
if(a == null) a = (E[])new Object[size()];
|
|
|
|
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
|
|
|
|
for(int i = 0;i<size();i++)
|
|
|
|
a[i] = (E)KEY_TO_OBJ(data[offset+i]);
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2021-01-07 15:14:51 +01:00
|
|
|
#if !TYPE_OBJECT
|
|
|
|
protected int findIndex(KEY_TYPE o) {
|
2021-01-08 21:12:20 +01:00
|
|
|
for(int i = length-1;i>=0;i--)
|
2021-01-21 21:35:23 +01:00
|
|
|
if(KEY_EQUALS(data[offset+i], o)) return i + offset;
|
2021-01-07 15:14:51 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
protected int findIndex(Object o) {
|
2021-01-08 21:12:20 +01:00
|
|
|
for(int i = length-1;i>=0;i--)
|
2021-01-07 15:14:51 +01:00
|
|
|
if(EQUALS_KEY_TYPE(data[offset+i], o)) return i + offset;
|
2020-12-13 23:41:09 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2021-01-08 21:12:20 +01:00
|
|
|
|
|
|
|
private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
|
|
|
|
int index;
|
|
|
|
int lastReturned = -1;
|
|
|
|
|
|
|
|
public SetIterator(int index) {
|
|
|
|
this.index = index;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean hasNext() {
|
|
|
|
return index < size();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE NEXT() {
|
2021-12-11 12:53:58 +01:00
|
|
|
if(!hasNext()) throw new NoSuchElementException();
|
2021-01-08 21:12:20 +01:00
|
|
|
lastReturned = index;
|
|
|
|
return data[index++];
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean hasPrevious() {
|
|
|
|
return index > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE PREVIOUS() {
|
2021-12-11 12:53:58 +01:00
|
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
2021-01-08 21:12:20 +01:00
|
|
|
lastReturned = index;
|
|
|
|
return data[index--];
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int nextIndex() {
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int previousIndex() {
|
|
|
|
return index-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void remove() {
|
|
|
|
if(lastReturned == -1)
|
|
|
|
throw new IllegalStateException();
|
|
|
|
SubSet.this.remove(data[lastReturned]);
|
|
|
|
if(lastReturned < index)
|
|
|
|
index--;
|
|
|
|
lastReturned = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if TYPE_OBJECT
|
|
|
|
@Override
|
|
|
|
public void set(Object e) { throw new UnsupportedOperationException(); }
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void add(Object e) { throw new UnsupportedOperationException(); }
|
|
|
|
|
|
|
|
#else
|
|
|
|
@Override
|
|
|
|
public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); }
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
|
|
|
|
|
|
|
|
#endif
|
|
|
|
@Override
|
|
|
|
public int skip(int amount) {
|
|
|
|
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
|
|
|
int steps = Math.min(amount, (size() - 1) - index);
|
|
|
|
index += steps;
|
|
|
|
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;
|
|
|
|
return steps;
|
|
|
|
}
|
|
|
|
}
|
2020-12-13 23:41:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
|
|
|
|
int index;
|
|
|
|
int lastReturned = -1;
|
|
|
|
|
|
|
|
public SetIterator(int index) {
|
|
|
|
this.index = index;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean hasNext() {
|
|
|
|
return index < size();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE NEXT() {
|
2021-12-11 12:53:58 +01:00
|
|
|
if(!hasNext()) throw new NoSuchElementException();
|
2020-12-13 23:41:09 +01:00
|
|
|
lastReturned = index;
|
|
|
|
return data[index++];
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean hasPrevious() {
|
|
|
|
return index > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE PREVIOUS() {
|
2021-12-11 12:53:58 +01:00
|
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
2020-12-13 23:41:09 +01:00
|
|
|
lastReturned = index;
|
|
|
|
return data[index--];
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int nextIndex() {
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int previousIndex() {
|
|
|
|
return index-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void remove() {
|
2021-12-11 12:53:58 +01:00
|
|
|
if(lastReturned == -1) throw new IllegalStateException();
|
2020-12-13 23:41:09 +01:00
|
|
|
ARRAY_SET.this.remove(data[lastReturned]);
|
2021-12-11 12:53:58 +01:00
|
|
|
if(lastReturned < index) index--;
|
2020-12-13 23:41:09 +01:00
|
|
|
lastReturned = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if TYPE_OBJECT
|
|
|
|
@Override
|
|
|
|
public void set(Object e) { throw new UnsupportedOperationException(); }
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void add(Object e) { throw new UnsupportedOperationException(); }
|
|
|
|
|
|
|
|
#else
|
|
|
|
@Override
|
|
|
|
public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); }
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
|
|
|
|
|
|
|
|
#endif
|
|
|
|
@Override
|
|
|
|
public int skip(int amount) {
|
|
|
|
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
|
|
|
int steps = Math.min(amount, (size() - 1) - index);
|
|
|
|
index += steps;
|
|
|
|
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;
|
|
|
|
return steps;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|