add different versions of IntList.insert and LongList.insert

The new methods are more flexible, so that you can insert
parts of an array.
This commit is contained in:
2018-09-23 15:28:37 +02:00
parent b99021d0f7
commit fef9af51cd
5 changed files with 376 additions and 54 deletions

View File

@@ -202,51 +202,118 @@ public final class IntList implements Serializable, Cloneable {
/**
* Inserts {@code values} at position {@code pos} into the list.
*
* @param pos the position to insert the elements
* @param values the elements to insert
* @param destPos the position to insert the elements
* @param values the elements to insert
* @throws IndexOutOfBoundsException if pos is out of bounds
* {@code pos < 0 || pos > size()}
* @throws NullPointerException if the given array is null
*/
public void insert(final int pos, final int... values) {
public void insert(final int destPos, final IntList values) {
final TriValueBool sourceIsSorted = values.isSorted() ? TriValueBool.TRUE : TriValueBool.FALSE;
insert(destPos, values.data, 0, values.size(), sourceIsSorted);
}
if (pos < 0) {
throw new IndexOutOfBoundsException("pos must not be negative, but was: " + pos);
}
if (pos > size) {
throw new IndexOutOfBoundsException("pos must be smaller than size(), but was: " + pos);
}
if (values == null) {
throw new NullPointerException("values parameter must not be null");
}
if (values.length == 0) {
/**
* Inserts {@code values} at position {@code pos} into the list.
*
* @param destPos the position to insert the elements
* @param source the elements to insert
* @param sourcePos starting position in the source array
* @param length number of elements to insert
* @throws IndexOutOfBoundsException if destPos is out of bounds, if sourcePos
* is out of bounds or if sourcePos + length
* is out of bounds
* @throws NullPointerException if the given array is null
*/
public void insert(final int destPos, final IntList source, final int sourcePos, final int length) {
// note: the sublist might be sorted even if the complete list is not
final TriValueBool sourceIsSorted = source.isSorted() ? TriValueBool.TRUE : TriValueBool.UNKNOWN;
insert(destPos, source.data, sourcePos, length, sourceIsSorted);
}
/**
* Inserts {@code values} at position {@code pos} into the list.
*
* @param destPos the position to insert the elements
* @param source the elements to insert
* @throws IndexOutOfBoundsException if pos is out of bounds
* @throws NullPointerException if the given array is null
*/
public void insert(final int destPos, final int... source) {
insert(destPos, source, 0, source.length, TriValueBool.UNKNOWN);
}
/**
* Inserts {@code values} at position {@code pos} into the list.
*
* @param destPos the position to insert the elements
* @param source the elements to insert
* @param sourcePos starting position in the source array
* @param length number of elements to insert
* @throws IndexOutOfBoundsException if destPos is out of bounds, if sourcePos
* is out of bounds or if sourcePos + length
* is out of bounds
* @throws NullPointerException if the given array is null
*/
public void insert(final int destPos, final int[] source, final int sourcePos, final int length) {
insert(destPos, source, sourcePos, length, TriValueBool.UNKNOWN);
}
private void insert(final int destPos, final int[] source, final int sourcePos, final int length,
final TriValueBool sourceIsSorted) {
if (length == 0) {
return;
}
if (destPos < 0) {
throw new IndexOutOfBoundsException("destPos must not be negative, but was: " + destPos);
}
if (destPos > size) {
throw new IndexOutOfBoundsException("destPos must not be larger than size(), but was: " + sourcePos);
}
if (sourcePos >= source.length) {
throw new IndexOutOfBoundsException("sourcePos must be smaller than source.length, but was: " + destPos);
}
if (sourcePos + length > source.length) {
throw new IndexOutOfBoundsException(
"sourcePos + length must not be larger than source.length, but was: " + (sourcePos + length));
}
ensureCapacity(values.length);
ensureCapacity(length);
// move everything after the insert position to make room for the new values
System.arraycopy(data, pos, data, pos + values.length, size - pos);
System.arraycopy(data, destPos, data, destPos + length, size - destPos);
// insert the new values
System.arraycopy(values, 0, data, pos, values.length);
size += values.length;
System.arraycopy(source, sourcePos, data, destPos, length);
size += length;
if (sorted) {
// compare with element before the insertion
sorted = pos == 0 ? sorted : data[pos - 1] <= data[pos];
sorted = destPos == 0 ? sorted : data[destPos - 1] <= data[destPos];
// check if the inserted values are sorted
for (int i = 1; i < values.length && sorted; i++) {
sorted = data[pos + i - 1] <= data[pos + i];
switch (sourceIsSorted) {
case TRUE:
// nothing to do, keep the current value of 'sorted'
break;
case FALSE:
sorted = false;
break;
case UNKNOWN:
for (int i = 1; i < length && sorted; i++) {
sorted = data[destPos + i - 1] <= data[destPos + i];
}
break;
default:
throw new IllegalStateException("unhandled enum value: " + sourceIsSorted);
}
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 = destPos + length < size()//
? data[destPos + length - 1] <= data[destPos + length]//
: sorted;
}
}
}
/**

View File

@@ -192,51 +192,118 @@ public final class LongList implements Serializable, Cloneable {
/**
* Inserts {@code values} at position {@code pos} into the list.
*
* @param pos the position to insert the elements
* @param values the elements to insert
* @throws IndexOutOfBoundsException if pos is out of bounds
* {@code pos < 0 || pos > size()}
* @param destPos the position to insert the elements
* @param values the elements to insert
* @throws IndexOutOfBoundsException if destPos is out of bounds
* @throws NullPointerException if the given array is null
*/
public void insert(final int pos, final long... values) {
public void insert(final int destPos, final LongList values) {
final TriValueBool sourceIsSorted = values.isSorted() ? TriValueBool.TRUE : TriValueBool.FALSE;
insert(destPos, values.data, 0, values.size(), sourceIsSorted);
}
if (pos < 0) {
throw new IndexOutOfBoundsException("pos must not be negative, but was: " + pos);
}
if (pos > size) {
throw new IndexOutOfBoundsException("pos must be smaller than size(), but was: " + pos);
}
if (values == null) {
throw new NullPointerException("values parameter must not be null");
}
if (values.length == 0) {
/**
* Inserts {@code values} at position {@code pos} into the list.
*
* @param destPos the position to insert the elements
* @param source the elements to insert
* @param sourcePos starting position in the source array
* @param length number of elements to insert
* @throws IndexOutOfBoundsException if destPos is out of bounds, if sourcePos
* is out of bounds or if sourcePos + length
* is out of bounds
* @throws NullPointerException if the given array is null
*/
public void insert(final int destPos, final LongList source, final int sourcePos, final int length) {
// note: the sublist might be sorted even if the complete list is not
final TriValueBool sourceIsSorted = source.isSorted() ? TriValueBool.TRUE : TriValueBool.UNKNOWN;
insert(destPos, source.data, sourcePos, length, sourceIsSorted);
}
/**
* Inserts {@code values} at position {@code pos} into the list.
*
* @param destPos the position to insert the elements
* @param source the elements to insert
* @throws IndexOutOfBoundsException if destPos is out of bounds
* @throws NullPointerException if the given array is null
*/
public void insert(final int destPos, final long... source) {
insert(destPos, source, 0, source.length, TriValueBool.UNKNOWN);
}
/**
* Inserts {@code values} at position {@code pos} into the list.
*
* @param destPos the position to insert the elements
* @param source the elements to insert
* @param sourcePos starting position in the source array
* @param length number of elements to insert
* @throws IndexOutOfBoundsException if destPos is out of bounds, if sourcePos
* is out of bounds or if sourcePos + length
* is out of bounds
* @throws NullPointerException if the given array is null
*/
public void insert(final int destPos, final long[] source, final int sourcePos, final int length) {
insert(destPos, source, sourcePos, length, TriValueBool.UNKNOWN);
}
private void insert(final int destPos, final long[] source, final int sourcePos, final int length,
final TriValueBool sourceIsSorted) {
if (length == 0) {
return;
}
if (destPos < 0) {
throw new IndexOutOfBoundsException("destPos must not be negative, but was: " + destPos);
}
if (destPos > size) {
throw new IndexOutOfBoundsException("destPos must not be larger than size(), but was: " + sourcePos);
}
if (sourcePos >= source.length) {
throw new IndexOutOfBoundsException("sourcePos must be smaller than source.length, but was: " + destPos);
}
if (sourcePos + length > source.length) {
throw new IndexOutOfBoundsException(
"sourcePos + length must not be larger than source.length, but was: " + (sourcePos + length));
}
ensureCapacity(values.length);
ensureCapacity(length);
// move everything after the insert position to make room for the new values
System.arraycopy(data, pos, data, pos + values.length, size - pos);
System.arraycopy(data, destPos, data, destPos + length, size - destPos);
// insert the new values
System.arraycopy(values, 0, data, pos, values.length);
size += values.length;
System.arraycopy(source, sourcePos, data, destPos, length);
size += length;
if (sorted) {
// compare with element before the insertion
sorted = pos == 0 ? sorted : data[pos - 1] <= data[pos];
sorted = destPos == 0 ? sorted : data[destPos - 1] <= data[destPos];
// check if the inserted values are sorted
for (int i = 1; i < values.length && sorted; i++) {
sorted = data[pos + i - 1] <= data[pos + i];
switch (sourceIsSorted) {
case TRUE:
// nothing to do, keep the current value of 'sorted'
break;
case FALSE:
sorted = false;
break;
case UNKNOWN:
for (int i = 1; i < length && sorted; i++) {
sorted = data[destPos + i - 1] <= data[destPos + i];
}
break;
default:
throw new IllegalStateException("unhandled enum value: " + sourceIsSorted);
}
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 = destPos + length < size()//
? data[destPos + length - 1] <= data[destPos + length]//
: sorted;
}
}
}
/**

View File

@@ -0,0 +1,8 @@
package org.lucares.collections;
/**
* Represents a boolean with three values: true, false and unknown
*/
enum TriValueBool {
TRUE, FALSE, UNKNOWN
}