add lastIndexOf

This commit is contained in:
2017-12-13 20:39:54 +01:00
parent 76e5dc403c
commit 25650b9638
2 changed files with 122 additions and 4 deletions

View File

@@ -29,6 +29,9 @@ public final class IntList implements Serializable, Cloneable {
// TODO wrapper that reverses the order. This implies, that IntList becomes an
// interface, or it could not be final anymore. Being an interface would make it
// possible to have unmodifiable lists, too.
// TODO memory optimization: add private method ensureExactCapacity, that does
// not make the list 50% larger. This is useful for addAll or internal usage
// where we know the exact size.
private static final long serialVersionUID = 2622570032686034909L;
@@ -634,7 +637,7 @@ public final class IntList implements Serializable, Cloneable {
}
/**
* Returns the index of the last occurrence of {@code value}, or -1 if it does
* Returns the index of the first occurrence of {@code value}, or -1 if it does
* not exist.
* <p>
* This method uses a binary search algorithm if the list is sorted.
@@ -642,7 +645,9 @@ public final class IntList implements Serializable, Cloneable {
* @param value
* the value
* @param offset
* the offset
* the offset (inclusive). There is no invalid value. If the offset
* is negative, then it behaves as if it was 0. If it is &gt;=
* {@link #size()}, then -1 is returned.
* @return the index, or -1
* @throws ArrayIndexOutOfBoundsException
* if offset is negative, or larger than the size of the list
@@ -653,14 +658,74 @@ public final class IntList implements Serializable, Cloneable {
public int indexOf(final int value, final int offset) {
int result = -1;
if (sorted) {
if (sorted && offset >= 0 && offset < size()) {
int insertionPoint = Arrays.binarySearch(data, offset, size(), value);
while (insertionPoint > offset && data[insertionPoint - 1] == value) {
insertionPoint--;
}
result = insertionPoint < 0 ? -1 : insertionPoint;
} else {
for (int i = offset; i < size; i++) {
final int start = Math.max(offset, 0);
for (int i = start; i < size; i++) {
if (data[i] == value) {
result = i;
break;
}
}
}
return result;
}
/**
* Returns the index of the last occurrence of {@code value} searching
* backwards, or -1 if it does not exist.
* <p>
* This method uses a binary search algorithm if the list is sorted.
*
* @param value
* the value
* @return the index, or -1
* @see #isSorted()
*/
public int lastIndexOf(final int value) {
return lastIndexOf(value, size() - 1);
}
/**
* Returns the index of the last occurrence of {@code value} searching backwards
* from {@code fromIndex}, or -1 if it does not exist.
* <p>
* This method uses a binary search algorithm if the list is sorted.
*
* @param value
* the value
* @param fromIndex
* the index the start the search from (inclusive). There is no
* invalid input. If {@code fromIndex} is &lt; 0, then -1 is
* returned. If it is larger than the length of the list, then it
* behaves as if it were {@link #size()}-1.
* @return the index, or -1
* @see #isSorted()
*/
public int lastIndexOf(final int value, final int fromIndex) {
int result = -1;
if (sorted) {
final int toIndex = Math.min(size - 1, fromIndex + 1); // toIndex is exclusive in binarySearch, but
// fromIndex is inclusive
if (toIndex > 0) {
int insertionPoint = Arrays.binarySearch(data, 0, toIndex, value);
// if value exists more than once, then binarySearch can find any one of them,
// but we are looking for the last occurrence
while (insertionPoint >= 0 && insertionPoint < fromIndex && data[insertionPoint + 1] == value) {
insertionPoint++;
}
result = insertionPoint < 0 ? -1 : insertionPoint;
}
} else {
final int startIndex = Math.min(size - 1, fromIndex);
for (int i = startIndex; i >= 0; i--) {
if (data[i] == value) {
result = i;
break;