add 'sorted' flag that keeps track whether the list is sorted

The flag can be used in indexOf or for a better retainAll
implementation.
This commit is contained in:
2017-12-02 20:24:32 +01:00
parent 7f3d4872ae
commit c7cacf1ad4
2 changed files with 337 additions and 12 deletions

View File

@@ -18,9 +18,10 @@ public final class IntList implements Serializable, Cloneable {
// TODO support Iterator
// TODO add mod counts
// TODO support sublists
// TODO add remember if list is sorted so we can use binary search in indexOf
// TODO use sorted flag in indexOf
// TODO add lastIndexOf
// TODO remove bounds checks that are handled by java, e.g. negative indices
// TODO clear
private static final long serialVersionUID = 2622570032686034909L;
@@ -41,6 +42,12 @@ public final class IntList implements Serializable, Cloneable {
private int index = 0;
/**
* Keeps track of whether or not the list is sorted. This allows us to use
* binary search for {@link #indexOf(int)}. An empty list is sorted.
*/
private boolean sorted = true;
/**
* Create a new {@link IntList} with initial capacity 10.
*/
@@ -77,6 +84,7 @@ public final class IntList implements Serializable, Cloneable {
data = new int[intList.getCapacity()];
System.arraycopy(intList.data, 0, data, 0, intList.size());
index = intList.size();
sorted = intList.sorted;
}
/**
@@ -123,6 +131,17 @@ public final class IntList implements Serializable, Cloneable {
return data.length;
}
/**
* Returns whether or not the list is sorted.
* <p>
* An empty list is sorted.
*
* @return true iff the list is sorted.
*/
public boolean isSorted() {
return sorted;
}
/**
* Adds {@code value} to the list.
*
@@ -133,6 +152,10 @@ public final class IntList implements Serializable, Cloneable {
ensureCapacity(1);
data[index] = value;
if (sorted) {
sorted = index == 0 ? sorted : data[index - 1] <= data[index];
}
index++;
}
@@ -159,15 +182,34 @@ public final class IntList implements Serializable, Cloneable {
if (values == null) {
throw new NullPointerException("values parameter must not be null");
}
if (values.length == 0) {
return;
}
ensureCapacity(values.length);
// move everything after the insert position to make room for the new values
System.arraycopy(data, pos, data, pos + values.length, values.length);
System.arraycopy(data, pos, data, pos + values.length, index - pos);
// insert the new values
System.arraycopy(values, 0, data, pos, values.length);
index += values.length;
if (sorted) {
// compare with element before the insertion
sorted = pos == 0 ? sorted : data[pos - 1] <= data[pos];
// check if the inserted values are sorted
for (int i = 1; i < values.length && sorted; i++) {
sorted = data[pos + i - 1] <= data[pos + i];
}
if (sorted) {
// compare last inserted element with next element in the list
sorted = pos + values.length < size()//
? data[pos + values.length - 1] <= data[pos + values.length]//
: sorted;
}
}
}
/**
@@ -191,6 +233,11 @@ public final class IntList implements Serializable, Cloneable {
}
data[pos] = value;
if (sorted) {
sorted = pos <= 0 ? sorted : data[pos - 1] <= data[pos];
sorted = pos + 1 >= size() ? sorted : data[pos] <= data[pos + 1];
}
}
/**
@@ -205,6 +252,13 @@ public final class IntList implements Serializable, Cloneable {
ensureCapacity(values.length);
System.arraycopy(values, 0, data, index, values.length);
if (sorted) {
for (int i = 0; i < values.length && sorted; i++) {
sorted = index + i - 1 < 0 ? sorted : data[index + i - 1] <= data[index + i];
}
}
index += values.length;
}
@@ -241,6 +295,8 @@ public final class IntList implements Serializable, Cloneable {
System.arraycopy(data, toIndex, data, fromIndex, numRemoved);
index = index - (toIndex - fromIndex);
sorted = size() <= 1 ? true : sorted; // lists of size 1 or smaller are always sorted
}
/**
@@ -268,6 +324,8 @@ public final class IntList implements Serializable, Cloneable {
}
}
index = insertPosition;
sorted = size() <= 1 ? true : sorted; // lists of size 1 or smaller are always sorted
}
/**
@@ -297,6 +355,7 @@ public final class IntList implements Serializable, Cloneable {
}
index = insertPosition;
sorted = size() <= 1 ? true : sorted; // lists of size 1 or smaller are always sorted
}
/**
@@ -334,10 +393,10 @@ public final class IntList implements Serializable, Cloneable {
* if the specified {@link UnaryIntOperator} is null
*/
public void replaceAll(final UnaryIntOperator operator) {
final int size = index;
for (int i = 0; i < size; i++) {
data[i] = operator.apply(data[i]);
for (int i = 0; i < index; i++) {
final int newValue = operator.apply(data[i]);
set(i, newValue);
}
}
@@ -418,6 +477,7 @@ public final class IntList implements Serializable, Cloneable {
*/
public void sort() {
Arrays.sort(data, 0, index);
sorted = true;
}
/**
@@ -426,6 +486,7 @@ public final class IntList implements Serializable, Cloneable {
*/
public void parallelSort() {
Arrays.parallelSort(data, 0, index);
sorted = true;
}
private void ensureCapacity(final int newElements) {