We are now to 16k tests. Fixed loads of issues.

-Added: Tests for Lists and Sets.
-Fixed: SubLists are now stable (they weren't before)
-Fixed: All the bugs that the unit tests found so far.
-Updated: ReadMe/Changelog
This commit is contained in:
2021-12-11 12:53:58 +01:00
parent eaa45976c7
commit e1df59d512
24 changed files with 747 additions and 219 deletions
@@ -3,11 +3,15 @@ package speiger.src.collections.PACKAGE.lists;
import java.util.Collection;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Objects;
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;
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
import speiger.src.collections.utils.SanityChecks;
/**
* Abstract implementation of the {@link LIST} interface.
@@ -15,9 +19,8 @@ import speiger.src.collections.PACKAGE.collections.ITERATOR;
*/
public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE
{
#if !TYPE_OBJECT
/**
* A Type-Specific implementation of add function that delegates to {@link #add(int, KEY_TYPE)}
* A Type-Specific implementation of add function that delegates to {@link List#add(int, Object)}
*/
@Override
public boolean add(KEY_TYPE e) {
@@ -25,6 +28,7 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
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.
@@ -213,7 +217,8 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
@Override
public LIST KEY_GENERIC_TYPE subList(int fromIndex, int toIndex) {
return new SUB_LIST(this, fromIndex, toIndex);
SanityChecks.checkArrayCapacity(size(), fromIndex, toIndex-fromIndex);
return new SubList(this, 0, fromIndex, toIndex);
}
@Override
@@ -228,6 +233,7 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) {
if(index < 0 || index > size()) throw new IndexOutOfBoundsException();
return new LIST_ITER(index);
}
@@ -239,134 +245,128 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
public ABSTRACT_LIST KEY_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); }
private class SUB_LIST extends ABSTRACT_LIST KEY_GENERIC_TYPE {
ABSTRACT_LIST KEY_GENERIC_TYPE l;
int offset;
private class SubList extends ABSTRACT_LIST KEY_GENERIC_TYPE
{
final ABSTRACT_LIST KEY_GENERIC_TYPE list;
final int parentOffset;
final int offset;
int size;
SUB_LIST(ABSTRACT_LIST KEY_GENERIC_TYPE l, int from, int to) {
if (from < 0) throw new IndexOutOfBoundsException("fromIndex = " + from);
else if (to > l.size()) throw new IndexOutOfBoundsException("toIndex = " + to);
else if (from > to) throw new IllegalArgumentException("fromIndex(" + from + ") > toIndex(" + to + ")");
this.l = l;
offset = from;
size = to - from;
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 e) {
checkAddRange(index);
l.add(index+offset, e);
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) {
checkAddRange(index);
int size = c.size();
if(size == 0) return false;
l.addAll(index + offset, l);
offset += size;
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) {
checkAddRange(index);
int size = c.size();
if(size == 0) return false;
l.addAll(index + offset, l);
offset += size;
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) {
checkAddRange(index);
int size = c.size();
if(size == 0) return false;
l.addAll(index + offset, l);
offset += size;
return true;
}
@Override
public boolean addAll(KEY_TYPE[] e, int offset, int length) {
if(length <= 0) return false;
l.addElements(this.offset, e, offset, length);
offset += length;
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) {
checkRange(from);
l.addElements(from + this.offset, a, offset, length);
size += 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) {
checkRange(from);
return l.getElements(from + this.offset, a, offset, length);
SanityChecks.checkArrayCapacity(size, from, length);
SanityChecks.checkArrayCapacity(a.length, offset, length);
return list.getElements(from+this.offset, a, offset, length);
}
@Override
public void removeElements(int from, int to) {
checkRange(from);
checkRange(to);
l.removeElements(from + offset, to + offset);
if(to-from <= 0) return;
checkSubRange(from);
checkSubRange(to);
list.removeElements(from+parentOffset, to+parentOffset);
size -= to - from;
}
#if TYPE_OBJECT
@Override
public <K> K[] extractElements(int from, int to, Class<K> clz) {
checkRange(from);
checkRange(to);
K[] a = l.extractElements(from + offset, to + offset, clz);
public <K> K[] extractElements(int from, int to, Class<K> type) {
checkSubRange(from);
checkSubRange(to);
K[] result = list.extractElements(from+parentOffset, to+parentOffset, type);
size -= to - from;
return a;
return result;
}
#else
@Override
public KEY_TYPE[] extractElements(int from, int to) {
checkRange(from);
checkRange(to);
KEY_TYPE[] a = l.extractElements(from + offset, to + offset);
checkSubRange(from);
checkSubRange(to);
KEY_TYPE[] result = list.extractElements(from+parentOffset, to+parentOffset);
size -= to - from;
return a;
return result;
}
#endif
@Override
public KEY_TYPE GET_KEY(int index) {
checkRange(index);
return l.GET_KEY(index + offset);
checkSubRange(index);
return list.GET_KEY(offset+index);
}
@Override
public KEY_TYPE set(int index, KEY_TYPE element) {
checkSubRange(index);
return list.set(offset+index, element);
}
@Override
public KEY_TYPE set(int index, KEY_TYPE e) {
checkRange(index);
return l.set(index + offset, e);
public KEY_TYPE swapRemove(int index) {
checkSubRange(index);
KEY_TYPE result = list.swapRemove(index+parentOffset);
size--;
return result;
}
@Override
public KEY_TYPE REMOVE(int index) {
checkRange(index);
int temp = l.size();
KEY_TYPE type = l.REMOVE(index + offset);
if(l.size() != temp) size--;
return type;
}
public KEY_TYPE swapRemove(int index) {
checkRange(index);
int temp = l.size();
KEY_TYPE type = l.swapRemove(index + offset);
if(l.size() != temp) size--;
return type;
checkSubRange(index);
KEY_TYPE result = list.REMOVE(index+parentOffset);
size--;
return result;
}
@Override
@@ -374,17 +374,114 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
return size;
}
private void checkRange(int index) {
@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(list, offset, fromIndex, toIndex);
}
protected void checkSubRange(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
private void checkAddRange(int index) {
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);
lastReturned = -1;
}
@Override
public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, (list.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;
}
}
}
private class LIST_ITER implements LIST_ITERATOR KEY_GENERIC_TYPE {
int index;
int lastReturned = -1;
@@ -400,8 +497,9 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
@Override
public KEY_TYPE NEXT() {
lastReturned = index;
return GET_KEY(index++);
if(!hasNext()) throw new NoSuchElementException();
int i = index++;
return GET_KEY((lastReturned = i));
}
@Override
@@ -411,8 +509,9 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
@Override
public KEY_TYPE PREVIOUS() {
lastReturned = index;
return GET_KEY(index--);
if(!hasPrevious()) throw new NoSuchElementException();
index--;
return GET_KEY((lastReturned = index));
}
@Override
@@ -427,25 +526,20 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
@Override
public void remove() {
if(lastReturned == -1)
throw new IllegalStateException();
if(lastReturned == -1) throw new IllegalStateException();
ABSTRACT_LIST.this.REMOVE(lastReturned);
if(lastReturned < index)
index--;
index = lastReturned;
lastReturned = -1;
}
@Override
public void set(KEY_TYPE e) {
if(lastReturned == -1)
throw new IllegalStateException();
if(lastReturned == -1) throw new IllegalStateException();
ABSTRACT_LIST.this.set(lastReturned, e);
}
@Override
public void add(KEY_TYPE e) {
if(lastReturned == -1)
throw new IllegalStateException();
ABSTRACT_LIST.this.add(index++, e);
lastReturned = -1;
}
@@ -1029,6 +1029,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
for(int i = 0;i<size;i++)
a[i] = (E)KEY_TO_OBJ(data[i]);
#endif
if (a.length > size) a[size] = null;
return a;
}
@@ -1037,6 +1038,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a.length < size) a = new KEY_TYPE[size];
System.arraycopy(data, 0, a, 0, size);
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
@@ -1138,6 +1140,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
#if PRIMITIVES
/**
* Returns a Java-Type-Specific Stream to reduce boxing/unboxing.
@@ -5,6 +5,7 @@ import java.util.Arrays;
import java.util.Comparator;
#endif
import java.util.Collection;
import java.util.NoSuchElementException;
import java.util.Objects;
#if TYPE_OBJECT
import java.util.function.BiFunction;
@@ -381,6 +382,12 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
return result;
}
@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 KEY_TYPE set(int index, KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
@@ -447,6 +454,7 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
else if(a.length < data.length) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), data.length);
for(int i = 0,m=data.length;i<m;i++)
a[i] = (E)KEY_TO_OBJ(data[i]);
if (a.length > data.length) a[data.length] = null;
return a;
}
@@ -455,6 +463,7 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a.length < data.length) a = new KEY_TYPE[data.length];
System.arraycopy(data, 0, a, 0, data.length);
if (a.length > data.length) a[data.length] = EMPTY_KEY_VALUE;
return a;
}
@@ -495,4 +504,69 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
*/
@Override
public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createArraySplititerator(data, data.length, 16464); }
private class LIST_ITER implements LIST_ITERATOR KEY_GENERIC_TYPE {
int index;
LIST_ITER(int index) {
this.index = index;
}
@Override
public boolean hasNext() {
return index < size();
}
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
return GET_KEY(index++);
}
@Override
public boolean hasPrevious() {
return index > 0;
}
@Override
public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException();
return GET_KEY(--index);
}
@Override
public int nextIndex() {
return index;
}
@Override
public int previousIndex() {
return index-1;
}
@Override
public void remove() { throw new UnsupportedOperationException(); }
@Override
public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@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;
}
}
}
@@ -9,6 +9,7 @@ import java.nio.JAVA_BUFFER;
import java.util.Collection;
import java.util.Iterator;
import java.util.Objects;
import java.util.NoSuchElementException;
import java.util.Spliterator;
#if PRIMITIVES
import java.util.Spliterator.JAVA_SPLIT_ITERATOR;
@@ -326,9 +327,8 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override
@Primitive
public int indexOf(Object o) {
if(o == null) return -1;
Entry KEY_GENERIC_TYPE entry = first;
for(int i = 0;entry != null;entry = entry.next) {
for(int i = 0;entry != null;entry = entry.next,i++) {
if(Objects.equals(KEY_TO_OBJ(entry.value), o)) return i;
}
return -1;
@@ -337,9 +337,8 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override
@Primitive
public int lastIndexOf(Object o) {
if(o == null) return -1;
Entry KEY_GENERIC_TYPE entry = last;
for(int i = size-1;entry != null;entry = entry.prev) {
for(int i = size-1;entry != null;entry = entry.prev,i--) {
if(Objects.equals(KEY_TO_OBJ(entry.value), o)) return i;
}
return -1;
@@ -354,7 +353,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override
public int indexOf(KEY_TYPE e) {
Entry entry = first;
for(int i = 0;entry != null;entry = entry.next) {
for(int i = 0;entry != null;entry = entry.next,i++) {
if(KEY_EQUALS(entry.value, e)) return i;
}
return -1;
@@ -363,26 +362,17 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override
public int lastIndexOf(KEY_TYPE e) {
Entry entry = last;
for(int i = size-1;entry != null;entry = entry.prev) {
for(int i = size-1;entry != null;entry = entry.prev,i--) {
if(KEY_EQUALS(entry.value, e)) return i;
}
return -1;
}
#endif
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return new ListIter(first, 0);
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator() {
return new ListIter(first, 0);
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) {
if(index == size-1) return new ListIter(last, index);
if(index < 0 || index > size()) throw new IndexOutOfBoundsException();
if(index == size) return new ListIter(null, index);
if(index == 0) return new ListIter(first, index);
return new ListIter(getNode(index), index);
}
@@ -564,7 +554,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override
public boolean removeFirst(KEY_TYPE e) {
if(size == 0) return false;
for(Entry KEY_GENERIC_TYPE entry = first;entry.next != null;entry = entry.next) {
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) {
if(KEY_EQUALS(entry.value, e)) {
unlink(entry);
return true;
@@ -576,7 +566,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override
public boolean removeLast(KEY_TYPE e) {
if(size == 0) return false;
for(Entry KEY_GENERIC_TYPE entry = last;entry.prev != null;entry = entry.prev) {
for(Entry KEY_GENERIC_TYPE entry = last;entry != null;entry = entry.prev) {
if(KEY_EQUALS(entry.value, e)) {
unlink(entry);
return true;
@@ -615,7 +605,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override
public boolean REMOVE_SWAP(KEY_TYPE e) {
if(size == 0) return false;
for(Entry KEY_GENERIC_TYPE entry = last;entry.prev != null;entry = entry.prev) {
for(Entry KEY_GENERIC_TYPE entry = last;entry != null;entry = entry.prev) {
if(KEY_EQUALS(entry.value, e)) {
if(entry.next == null) {
unlinkLast(entry);
@@ -649,7 +639,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override
public boolean remove(Object e) {
if(size <= 0) return false;
for(Entry KEY_GENERIC_TYPE entry = first;entry.next != null;entry = entry.next) {
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) {
if(KEY_EQUALS(entry.value, e)) {
unlink(entry);
return true;
@@ -949,6 +939,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) {
a[i++] = (E)KEY_TO_OBJ(entry.value);
}
if (a.length > size) a[size] = null;
return a;
}
@@ -958,8 +949,9 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
if(a.length < size) a = new KEY_TYPE[size];
int i = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) {
a[i++] = KEY_TO_OBJ(entry.value);
a[i++] = entry.value;
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
@@ -1118,23 +1110,23 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
private class ListIter implements LIST_ITERATOR KEY_GENERIC_TYPE
{
Entry KEY_GENERIC_TYPE node;
Entry KEY_GENERIC_TYPE next;
Entry KEY_GENERIC_TYPE lastReturned;
int index;
ListIter(Entry KEY_GENERIC_TYPE node, int index) {
this.node = node;
ListIter(Entry KEY_GENERIC_TYPE next, int index) {
this.next = next;
this.index = index;
}
@Override
public boolean hasNext() {
return node != null;
return index < size;
}
@Override
public boolean hasPrevious() {
return node != null;
return index > 0;
}
@Override
@@ -1150,23 +1142,26 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override
public void remove() {
if(lastReturned == null) throw new IllegalStateException();
if(lastReturned.next == node) index--;
Entry KEY_GENERIC_TYPE lastNext = lastReturned.next;
unlink(lastReturned);
if (next == lastReturned) next = lastNext;
else index--;
lastReturned = null;
}
@Override
public KEY_TYPE PREVIOUS() {
lastReturned = node;
node = node.prev;
if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = next = (next == null) ? last : next.prev;
index--;
return lastReturned.value;
}
@Override
public KEY_TYPE NEXT() {
lastReturned = node;
node = node.next;
if(!hasNext()) throw new NoSuchElementException();
lastReturned = next;
next = next.next;
index++;
return lastReturned.value;
}
@@ -1179,11 +1174,10 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override
public void add(KEY_TYPE e) {
if(lastReturned == null) throw new IllegalStateException();
if(node.next == null) linkLast(e);
else linkBefore(e, node);
lastReturned = null;
index++;
lastReturned = null;
if (next == null) linkLast(e);
else linkBefore(e, next);
index++;
}
}
@@ -1389,6 +1389,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
private class MapIterator {
int pos = nullIndex;
int returnedPos = -1;
int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull;
@@ -1420,6 +1421,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
returnedPos = pos;
if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE;
int value = findIndex(wrapped.GET_KEY(nextIndex));
@@ -1439,9 +1441,10 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
}
else if(lastReturned >= 0) shiftKeys(lastReturned);
else if(returnedPos >= 0) shiftKeys(returnedPos);
else {
CUSTOM_HASH_MAP.this.remove(wrapped.GET_KEY(-lastReturned - 1));
CUSTOM_HASH_MAP.this.remove(wrapped.GET_KEY(-returnedPos - 1));
lastReturned = -1;
return;
}
size--;
@@ -1345,6 +1345,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
private class MapIterator {
int pos = nullIndex;
int returnedPos = -1;
int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull;
@@ -1376,6 +1377,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
returnedPos = pos;
if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE;
int value = findIndex(wrapped.GET_KEY(nextIndex));
@@ -1395,9 +1397,10 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
}
else if(lastReturned >= 0) shiftKeys(lastReturned);
else if(returnedPos >= 0) shiftKeys(returnedPos);
else {
HASH_MAP.this.remove(wrapped.GET_KEY(-lastReturned - 1));
HASH_MAP.this.remove(wrapped.GET_KEY(-returnedPos - 1));
lastReturned = -1;
return;
}
size--;
@@ -261,7 +261,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
newValues[pos] = b[i];
continue;
}
while(KEY_EQUALS_NOT_NULL((current = newKeys[pos = (++pos & mask)]))) {
while(KEY_EQUALS_NOT_NULL((current = newKeys[pos = (++pos & newMask)]))) {
if(KEY_EQUALS(current, o)) {
found = false;
newValues[pos] = b[i];
@@ -202,8 +202,11 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value) {
int index = findIndex(key);
if(index >= 0) insertIndex(size++, key, value);
return getDefaultReturnValue();
if(index < 0) {
insertIndex(size++, key, value);
return getDefaultReturnValue();
}
return values[index];
}
#if VALUE_PRIMITIVES
@@ -463,6 +466,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
if(index == -1) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
@@ -481,6 +485,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
if(index == -1) {
VALUE_TYPE newValue = mappingFunction.GET_VALUE(key);
@@ -488,11 +493,18 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
insertIndex(size++, key, newValue);
return newValue;
}
return values[index];
VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = mappingFunction.GET_VALUE(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
return newValue;
}
@Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider);
int index = findIndex(key);
if(index == -1) {
VALUE_TYPE newValue = valueProvider.VALUE_GET_KEY();
@@ -500,13 +512,20 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
insertIndex(size++, key, newValue);
return newValue;
}
return values[index];
VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = valueProvider.VALUE_GET_KEY();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
if(index == -1) return getDefaultReturnValue();
if(index == -1 || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
removeIndex(index);
@@ -518,8 +537,12 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if VALUE_OBJECT
Objects.requireNonNull(value);
#endif
int index = findIndex(key);
VALUE_TYPE newValue = index == -1 ? value : mappingFunction.APPLY_VALUE(values[index], value);
VALUE_TYPE newValue = index == -1 || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? value : mappingFunction.APPLY_VALUE(values[index], value);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
if(index >= 0)
removeIndex(index);
@@ -535,7 +558,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(m)) {
KEY_TYPE key = entry.ENTRY_KEY();
int index = findIndex(key);
VALUE_TYPE newValue = index == -1 ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE());
VALUE_TYPE newValue = index == -1 || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE());
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
if(index >= 0)
removeIndex(index);
@@ -683,21 +706,18 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
#endif
protected int findIndex(Object key, Object value) {
if(key == null || value == null) return -1;
for(int i = size-1;i>=0;i--)
if(EQUALS_KEY_TYPE(keys[i], key) && EQUALS_VALUE_TYPE(values[i], value)) return i;
return -1;
}
protected int findIndex(Object key) {
if(key == null) return -1;
for(int i = size-1;i>=0;i--)
if(EQUALS_KEY_TYPE(keys[i], key)) return i;
return -1;
}
protected int findValue(Object value) {
if(value == null) return -1;
for(int i = size-1;i>=0;i--)
if(EQUALS_VALUE_TYPE(values[i], value)) return i;
return -1;
@@ -1069,21 +1089,18 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
#endif
protected int findIndex(Object key, Object value) {
if(key == null || value == null) return -1;
for(int i = length-1;i>=0;i--)
if(EQUALS_KEY_TYPE(keys[offset+i], key) && EQUALS_VALUE_TYPE(values[offset+i], value)) return i+offset;
return -1;
}
protected int findIndex(Object key) {
if(key == null) return -1;
for(int i = length-1;i>=0;i--)
if(EQUALS_KEY_TYPE(keys[offset+i], key)) return i+offset;
return -1;
}
protected int findValue(Object value) {
if(value == null) return -1;
for(int i = length-1;i>=0;i--)
if(EQUALS_VALUE_TYPE(values[offset+i], value)) return i+offset;
return -1;
@@ -1268,8 +1285,14 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Deprecated
public boolean contains(Object o) {
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) return SubMap.this.containsKey(((MAP.Entry KEY_VALUE_GENERIC_TYPE)o).ENTRY_KEY());
return SubMap.this.containsKey(((Map.Entry<?, ?>)o).getKey());
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
return SubMap.this.findIndex(entry.ENTRY_KEY(), entry.ENTRY_VALUE()) >= 0;
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
return ARRAY_MAP.this.findIndex(entry.getKey(), entry.getValue()) >= 0;
}
}
return false;
}
@@ -1318,7 +1341,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public boolean remove(Object o) {
int oldSize = length;
remove(o);
SubMap.this.remove(o);
return length != oldSize;
}
@@ -1329,7 +1352,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public boolean remove(KEY_TYPE o) {
int oldSize = length;
remove(o);
SubMap.this.remove(o);
return length != oldSize;
}
@@ -1737,12 +1760,14 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException();
int returnIndex = offset+index;
lastReturned = index--;
return returnIndex;
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
int returnIndex = offset+index;
lastReturned = index++;
return returnIndex;
@@ -1944,8 +1969,16 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Deprecated
public boolean contains(Object o) {
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) return ARRAY_MAP.this.containsKey(((MAP.Entry KEY_VALUE_GENERIC_TYPE)o).ENTRY_KEY());
return ARRAY_MAP.this.containsKey(((Map.Entry<?, ?>)o).getKey());
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
int index = ARRAY_MAP.this.findIndex(entry.ENTRY_KEY());
if(index >= 0) return VALUE_EQUALS(entry.ENTRY_VALUE(), ARRAY_MAP.this.values[index]);
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
int index = ARRAY_MAP.this.findIndex(entry.getKey());
if(index >= 0) return Objects.equals(entry.getValue(), VALUE_TO_OBJ(ARRAY_MAP.this.values[index]));
}
}
return false;
}
@@ -1994,7 +2027,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public boolean remove(Object o) {
int oldSize = size;
remove(o);
ARRAY_MAP.this.remove(o);
return size != oldSize;
}
@@ -2005,7 +2038,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public boolean remove(KEY_TYPE o) {
int oldSize = size;
remove(o);
ARRAY_MAP.this.remove(o);
return size != oldSize;
}
@@ -2401,11 +2434,13 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = index;
return index--;
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
lastReturned = index;
return index++;
}
@@ -2480,7 +2515,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public String toString() {
return KEY_TO_STRING(keys[index]) + "->" + VALUE_TO_STRING(values[index]);
return KEY_TO_STRING(keys[index]) + "=" + VALUE_TO_STRING(values[index]);
}
}
}
@@ -183,6 +183,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
#endif
@Override
public boolean containsKey(Object key) {
if(!keyType.isInstance(key)) return false;
return isSet(((T)key).ordinal());
}
@@ -190,7 +191,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
@Override
public boolean containsValue(Object value) {
for(int i = 0;i<values.length;i++)
if(VALUE_EQUALS(value, values[i])) return true;
if(isSet(i) && VALUE_EQUALS(value, values[i])) return true;
return false;
}
@@ -198,13 +199,25 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
@Override
public boolean containsValue(VALUE_TYPE value) {
for(int i = 0;i<values.length;i++)
if(VALUE_EQUALS(value, values[i])) return true;
if(isSet(i) && VALUE_EQUALS(value, values[i])) return true;
return false;
}
#endif
@Override
public CLASS_VALUE_TYPE remove(Object key) {
if(!keyType.isInstance(key)) return getDefaultReturnValue();
int index = ((T)key).ordinal();
if(!isSet(index)) return getDefaultReturnValue();
clear(index);
VALUE_TYPE result = values[index];
values[index] = EMPTY_VALUE;
return result;
}
@Override
public VALUE_TYPE rem(T key) {
if(!keyType.isInstance(key)) return getDefaultReturnValue();
int index = key.ordinal();
if(!isSet(index)) return getDefaultReturnValue();
clear(index);
@@ -246,6 +259,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
#endif
@Override
public VALUE_TYPE GET_VALUE(T key) {
if(!keyType.isInstance(key)) return getDefaultReturnValue();
int index = key.ordinal();
return isSet(index) ? values[index] : getDefaultReturnValue();
}
@@ -253,6 +267,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
#if VALUE_OBJECT
@Override
public VALUE_TYPE getOrDefault(Object key, VALUE_TYPE defaultValue) {
if(!keyType.isInstance(key)) return defaultValue;
int index = ((T)key).ordinal();
return isSet(index) ? values[index] : defaultValue;
}
@@ -260,6 +275,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
#else
@Override
public VALUE_TYPE getOrDefault(T key, VALUE_TYPE defaultValue) {
if(!keyType.isInstance(key)) return defaultValue;
int index = key.ordinal();
return isSet(index) ? values[index] : defaultValue;
}
@@ -347,7 +363,13 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
values[index] = newValue;
return newValue;
}
return values[index];
VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = mappingFunction.GET_VALUE(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
return newValue;
}
@Override
@@ -360,13 +382,19 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
values[index] = newValue;
return newValue;
}
return values[index];
VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = valueProvider.VALUE_GET_KEY();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(T key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
int index = key.ordinal();
if(!isSet(index)) return getDefaultReturnValue();
if(!isSet(index) || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
clear(index);
@@ -380,7 +408,10 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
@Override
public VALUE_TYPE MERGE(T key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
int index = key.ordinal();
VALUE_TYPE newValue = !isSet(index) ? value : mappingFunction.APPLY_VALUE(values[index], value);
#if VALUE_OBJECT
Objects.requireNonNull(value);
#endif
VALUE_TYPE newValue = !isSet(index) || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? value : mappingFunction.APPLY_VALUE(values[index], value);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
if(isSet(index)) {
clear(index);
@@ -401,7 +432,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(m)) {
T key = entry.ENTRY_KEY();
int index = key.ordinal();
VALUE_TYPE newValue = !isSet(index) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE());
VALUE_TYPE newValue = !isSet(index) || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE());
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
if(isSet(index)) {
clear(index);
@@ -424,6 +455,11 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
Arrays.fill(values, EMPTY_VALUE);
}
@Override
public int size() {
return size;
}
protected void onNodeAdded(int index) {
}
@@ -433,9 +469,9 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
}
protected void set(int index) {
size++;
present[index >> 6] |= (1L << index);
onNodeAdded(index);
present[index >> 6] |= (1L << index);
size++;
}
protected void clear(int index) {
size--;
@@ -452,7 +488,20 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
@Override
public boolean contains(Object o) {
if(o instanceof Map.Entry) return containsKey(((Map.Entry<?, ?>)o).getKey());
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
if(!keyType.isInstance(entry.ENTRY_KEY())) return false;
int index = ((T)entry.ENTRY_KEY()).ordinal();
if(index >= 0 && ENUM_MAP.this.isSet(index)) return VALUE_EQUALS(entry.ENTRY_VALUE(), ENUM_MAP.this.values[index]);
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
if(!keyType.isInstance(entry.getKey())) return false;
int index = ((T)entry.getKey()).ordinal();
if(index >= 0 && ENUM_MAP.this.isSet(index)) return Objects.equals(entry.getValue(), VALUE_TO_OBJ(ENUM_MAP.this.values[index]));
}
}
return false;
}
@@ -548,8 +597,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
class EntryIterator extends MapIterator implements ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
int index = nextEntry();
return new BasicEntry<>(keys[index], values[index]);
return new MapEntry(nextEntry());
}
}
@@ -584,13 +632,74 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
lastReturnValue = nextIndex;
return nextIndex;
nextIndex = -1;
return lastReturnValue;
}
public void remove() {
if(lastReturnValue == -1) throw new IllegalStateException();
clear(lastReturnValue);
values[lastReturnValue] = EMPTY_VALUE;
lastReturnValue = -1;
}
}
protected class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> {
public int index = -1;
public MapEntry() {}
public MapEntry(int index) {
this.index = index;
}
@Override
public KEY_TYPE ENTRY_KEY() {
return keys[index];
}
@Override
public VALUE_TYPE ENTRY_VALUE() {
return values[index];
}
@Override
public VALUE_TYPE setValue(VALUE_TYPE value) {
VALUE_TYPE oldValue = values[index];
values[index] = value;
return oldValue;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Map.Entry) {
if(obj instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj;
return KEY_EQUALS(keys[index], entry.ENTRY_KEY()) && VALUE_EQUALS(values[index], entry.ENTRY_VALUE());
}
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj;
Object key = entry.getKey();
Object value = entry.getValue();
#if TYPE_OBJECT && VALUE_OBJECT
return KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], value);
#else if TYPE_OBJECT
return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value));
#else if VALUE_OBJECT
return key instanceof CLASS_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], value);
#else
return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value));
#endif
}
return false;
}
@Override
public int hashCode() {
return KEY_TO_HASH(keys[index]) ^ VALUE_TO_HASH(values[index]);
}
@Override
public String toString() {
return KEY_TO_STRING(keys[index]) + "=" + VALUE_TO_STRING(values[index]);
}
}
}
@@ -109,7 +109,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
links = enumMap.links.clone();
size = enumMap.size;
}
if(map instanceof ENUM_MAP) {
else if(map instanceof ENUM_MAP) {
ENUM_MAP KEY_VALUE_GENERIC_TYPE enumMap = (ENUM_MAP KEY_VALUE_GENERIC_TYPE)map;
keyType = enumMap.keyType;
keys = enumMap.keys;
@@ -156,7 +156,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
links = enumMap.links.clone();
size = enumMap.size;
}
if(map instanceof ENUM_MAP) {
else if(map instanceof ENUM_MAP) {
ENUM_MAP KEY_VALUE_GENERIC_TYPE enumMap = (ENUM_MAP KEY_VALUE_GENERIC_TYPE)map;
keyType = enumMap.keyType;
keys = enumMap.keys;
@@ -519,8 +519,18 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Deprecated
public boolean contains(Object o) {
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) return LINKED_ENUM_MAP.this.containsKey(((MAP.Entry KEY_VALUE_GENERIC_TYPE)o).ENTRY_KEY());
return LINKED_ENUM_MAP.this.containsKey(((Map.Entry<?, ?>)o).getKey());
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
if(!keyType.isInstance(entry.ENTRY_KEY())) return false;
int index = ((T)entry.ENTRY_KEY()).ordinal();
if(index >= 0 && LINKED_ENUM_MAP.this.isSet(index)) return VALUE_EQUALS(entry.ENTRY_VALUE(), LINKED_ENUM_MAP.this.values[index]);
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
if(!keyType.isInstance(entry.getKey())) return false;
int index = ((T)entry.getKey()).ordinal();
if(index >= 0 && LINKED_ENUM_MAP.this.isSet(index)) return Objects.equals(entry.getValue(), VALUE_TO_OBJ(LINKED_ENUM_MAP.this.values[index]));
}
}
return false;
}
@@ -572,7 +582,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Override
public boolean remove(Object o) {
int oldSize = size;
remove(o);
LINKED_ENUM_MAP.this.remove(o);
return size != oldSize;
}
@@ -585,7 +595,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Override
public boolean remove(T o) {
int oldSize = size;
remove(o);
LINKED_ENUM_MAP.this.remove(o);
return size != oldSize;
}
@@ -887,6 +897,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
previous = (int)(links[current] >>> 32);
}
else next = (int)links[current];
size--;
if(previous == -1) firstIndex = next;
else links[previous] ^= ((links[previous] ^ (next & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
@@ -894,6 +905,8 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
if (next == -1) lastIndex = previous;
else links[next] ^= ((links[next] ^ ((previous & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
values[current] = EMPTY_VALUE;
present[current >> 6] &= ~(1L << current);
current = -1;
}
public int previousEntry() {
@@ -985,7 +998,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Override
public String toString() {
return KEY_TO_STRING(keys[index]) + "->" + VALUE_TO_STRING(values[index]);
return KEY_TO_STRING(keys[index]) + "=" + VALUE_TO_STRING(values[index]);
}
}
}
@@ -234,7 +234,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
@Override
public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value) {
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
if(tree == null) {
tree = first = last = new EntryKV_BRACES(key, value, null);
@@ -271,7 +271,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
@Override
public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value) {
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
if(tree == null) {
tree = first = last = new EntryKV_BRACES(key, value, null);
@@ -309,7 +309,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
@Override
public VALUE_TYPE addTo(KEY_TYPE key, VALUE_TYPE value) {
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
if(tree == null) {
tree = first = last = new EntryKV_BRACES(key, value, null);
@@ -521,7 +521,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
@@ -543,7 +543,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
@@ -564,7 +564,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
@@ -585,7 +585,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue())) return getDefaultReturnValue();
@@ -602,7 +602,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
VALUE_TYPE newValue = entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue()) ? value : mappingFunction.APPLY_VALUE(entry.value, value);
@@ -899,6 +899,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
}
}
protected void validate(KEY_TYPE k) { compare(k, k); }
protected int compare(KEY_TYPE k, KEY_TYPE v) { return comparator != null ? comparator.compare(k, v) : COMPAREABLE_TO_KEY(k, v);}
/** From CLR */
@@ -1532,13 +1533,13 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
AVL_TREE_MAP.Entry KEY_VALUE_GENERIC_TYPE subEntry = m.findNode(entry.ENTRY_KEY());
if(subEntry != null) return VALUE_EQUALS(entry.ENTRY_VALUE(), subEntry.value);
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
#if !TYPE_OBJECT
if(!(entry.getKey() instanceof CLASS_TYPE)) return false;
#endif
@@ -1938,13 +1939,13 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
AVL_TREE_MAP.Entry KEY_VALUE_GENERIC_TYPE subEntry = AVL_TREE_MAP.this.findNode(entry.ENTRY_KEY());
if(subEntry != null) return VALUE_EQUALS(entry.ENTRY_VALUE(), subEntry.value);
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
#if !TYPE_OBJECT
if(!(entry.getKey() instanceof CLASS_TYPE)) return false;
#endif
@@ -234,7 +234,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
@Override
public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value) {
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
if(tree == null) {
tree = first = last = new EntryKV_BRACES(key, value, null);
@@ -271,7 +271,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
@Override
public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value) {
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
if(tree == null) {
@@ -310,7 +310,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
@Override
public VALUE_TYPE addTo(KEY_TYPE key, VALUE_TYPE value) {
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
if(tree == null) {
tree = first = last = new EntryKV_BRACES(key, value, null);
@@ -521,7 +521,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
@@ -543,7 +543,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
@@ -564,7 +564,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
@@ -585,7 +585,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue())) return getDefaultReturnValue();
@@ -602,7 +602,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
VALUE_TYPE newValue = entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue()) ? value : mappingFunction.APPLY_VALUE(entry.value, value);
@@ -905,6 +905,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
}
}
protected void validate(KEY_TYPE k) { compare(k, k); }
protected int compare(KEY_TYPE k, KEY_TYPE v) { return comparator != null ? comparator.compare(k, v) : COMPAREABLE_TO_KEY(k, v);}
protected static GENERIC_KEY_VALUE_BRACES boolean isBlack(Entry KEY_VALUE_GENERIC_TYPE p) { return p == null || p.isBlack(); }
protected static GENERIC_KEY_VALUE_BRACES Entry KEY_VALUE_GENERIC_TYPE parentOf(Entry KEY_VALUE_GENERIC_TYPE p) { return (p == null ? null : p.parent); }
@@ -1587,13 +1588,13 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
RB_TREE_MAP.Entry KEY_VALUE_GENERIC_TYPE subEntry = m.findNode(entry.ENTRY_KEY());
if(subEntry != null) return VALUE_EQUALS(entry.ENTRY_VALUE(), subEntry.value);
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
#if !TYPE_OBJECT
if(!(entry.getKey() instanceof CLASS_TYPE)) return false;
#endif
@@ -1993,13 +1994,13 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
RB_TREE_MAP.Entry KEY_VALUE_GENERIC_TYPE subEntry = RB_TREE_MAP.this.findNode(entry.ENTRY_KEY());
if(subEntry != null) return VALUE_EQUALS(entry.ENTRY_VALUE(), subEntry.value);
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
#if !TYPE_OBJECT
if(!(entry.getKey() instanceof CLASS_TYPE)) return false;
#endif
@@ -213,6 +213,9 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#endif
@Override
public boolean add(KEY_TYPE o) {
#if TYPE_OBJECT
validate(o);
#endif
if(tree == null) {
tree = first = last = new EntryBRACES(o, null);
size++;
@@ -242,7 +245,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
}
fixAfterInsertion(adding);
size++;
return false;
return true;
}
@Override
@@ -652,6 +655,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
}
}
protected void validate(KEY_TYPE k) { compare(k, k); }
protected int compare(KEY_TYPE k, KEY_TYPE v) { return comparator != null ? comparator.compare(k, v) : COMPAREABLE_TO_KEY(k, v);}
/** From CLR */
@@ -74,8 +74,8 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
* @throws NegativeArraySizeException if the length is negative
*/
public ARRAY_SET(KEY_TYPE[] array, int length) {
data = Arrays.copyOf(array, length);
size = length;
this(length);
addAll(array, length);
}
/**
@@ -548,6 +548,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
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());
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
@@ -568,6 +569,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
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]);
if (a.length > size) a[size] = null;
return a;
}
@@ -841,6 +843,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
lastReturned = index;
return data[index++];
}
@@ -852,6 +855,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
@Override
public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = index;
return data[index--];
}
@@ -924,6 +928,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
lastReturned = index;
return data[index++];
}
@@ -935,6 +940,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
@Override
public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = index;
return data[index--];
}
@@ -951,11 +957,9 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
@Override
public void remove() {
if(lastReturned == -1)
throw new IllegalStateException();
if(lastReturned == -1) throw new IllegalStateException();
ARRAY_SET.this.remove(data[lastReturned]);
if(lastReturned < index)
index--;
if(lastReturned < index) index--;
lastReturned = -1;
}
@@ -190,7 +190,18 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
{
KEY_TYPE o = a[i];
if(KEY_EQUALS_NULL(o)) {
if(!containsNull) size++;
if(!containsNull) {
size++;
if(prev != -1) {
newLinks[prev] ^= ((newLinks[prev] ^ (newSize & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
newLinks[newSize] ^= ((newLinks[newSize] ^ ((prev & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
prev = newSize;
}
else {
prev = firstIndex = newSize;
newLinks[newSize] = -1L;
}
}
containsNull = true;
continue;
}
@@ -199,7 +210,7 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
KEY_TYPE current = newKeys[pos];
if(KEY_EQUALS_NOT_NULL(current)) {
if(KEY_EQUALS(current, o)) continue;
while(KEY_EQUALS_NOT_NULL((current = newKeys[pos = (++pos & mask)]))) {
while(KEY_EQUALS_NOT_NULL((current = newKeys[pos = (++pos & newMask)]))) {
if(KEY_EQUALS(current, o)) {
found = false;
break;
@@ -220,7 +231,7 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
}
}
}
nullIndex = size;
nullIndex = newSize;
mask = newMask;
keys = newKeys;
links = newLinks;
@@ -602,6 +602,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
private class SetIterator implements ITERATOR KEY_GENERIC_TYPE {
int pos = nullIndex;
int returnedPos = -1;
int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull;
@@ -634,6 +635,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
returnedPos = pos;
if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE;
KEY_TYPE value = wrapped.GET_KEY(nextIndex);
@@ -652,9 +654,10 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
}
else if(pos >= 0) shiftKeys(pos);
else if(returnedPos >= 0) shiftKeys(returnedPos);
else {
CUSTOM_HASH_SET.this.remove(wrapped.GET_KEY(-pos - 1));
CUSTOM_HASH_SET.this.remove(wrapped.GET_KEY(-returnedPos - 1));
lastReturned = -1;
return;
}
size--;
@@ -559,6 +559,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
private class SetIterator implements ITERATOR KEY_GENERIC_TYPE {
int pos = nullIndex;
int returnedPos = -1;
int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull;
@@ -592,6 +593,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
returnedPos = pos;
if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE;
KEY_TYPE value = wrapped.GET_KEY(nextIndex);
@@ -610,9 +612,10 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
}
else if(pos >= 0) shiftKeys(pos);
else if(returnedPos >= 0) shiftKeys(returnedPos);
else {
HASH_SET.this.remove(wrapped.GET_KEY(-pos - 1));
HASH_SET.this.remove(wrapped.GET_KEY(-returnedPos - 1));
lastReturned = -1;
return;
}
size--;
@@ -213,6 +213,9 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#endif
@Override
public boolean add(KEY_TYPE o) {
#if TYPE_OBJECT
validate(o);
#endif
if(tree == null) {
tree = first = last = new EntryBRACES(o, null);
size++;
@@ -242,7 +245,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
}
fixAfterInsertion(adding);
size++;
return false;
return true;
}
@Override
@@ -660,6 +663,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
}
}
protected void validate(KEY_TYPE k) { compare(k, k); }
protected int compare(KEY_TYPE k, KEY_TYPE v) { return comparator != null ? comparator.compare(k, v) : COMPAREABLE_TO_KEY(k, v);}
protected static GENERIC_KEY_BRACES boolean isBlack(Entry KEY_GENERIC_TYPE p) { return p == null || p.isBlack(); }
protected static GENERIC_KEY_BRACES Entry KEY_GENERIC_TYPE parentOf(Entry KEY_GENERIC_TYPE p) { return (p == null ? null : p.parent); }