-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
17ae7e8
commit cca1ed4
Showing
16 changed files
with
2,275 additions
and
1 deletion.
There are no files selected for viewing
173 changes: 173 additions & 0 deletions
173
...n/src/main/java/org.jhotdraw8.icollection/org/jhotdraw8/icollection/impl/ArrayHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
/* | ||
* @(#)ArrayHelper.java | ||
* Copyright © 2022 The authors and contributors of JHotDraw. MIT License. | ||
*/ | ||
|
||
package org.jhotdraw8.icollection.impl; | ||
|
||
import org.jhotdraw8.annotation.NonNull; | ||
|
||
import java.lang.reflect.Array; | ||
import java.util.Arrays; | ||
import java.util.Objects; | ||
import java.util.function.BiPredicate; | ||
|
||
/** | ||
* Provides static helper methods for arrays. | ||
*/ | ||
public class ArrayHelper { | ||
/** | ||
* Don't let anyone instantiate this class. | ||
*/ | ||
private ArrayHelper() { | ||
} | ||
|
||
/** | ||
* Checks if the elements in two sub-arrays are equal to one another | ||
* in the same order. | ||
* | ||
* @param a array a | ||
* @param aFrom from-index | ||
* @param aTo to-index | ||
* @param b array b (can be the same as array a) | ||
* @param bFrom from-index | ||
* @param bTo to-index | ||
* @return true if the two sub-arrays have the same length and | ||
* if the elements are equal to one another in the same order | ||
*/ | ||
public static <T> boolean equals(T @NonNull [] a, int aFrom, int aTo, | ||
T @NonNull [] b, int bFrom, int bTo) { | ||
return equals(a, aFrom, aTo, b, bFrom, bTo, Objects::equals); | ||
} | ||
|
||
/** | ||
* Checks if the elements in two sub-arrays are equal to one another | ||
* in the same order. | ||
* | ||
* @param a array a | ||
* @param aFrom from-index | ||
* @param aTo to-index | ||
* @param b array b (can be the same as array a) | ||
* @param bFrom from-index | ||
* @param bTo to-index | ||
* @param cmp the predicate that checks if two elements are equal | ||
* @return true if the two sub-arrays have the same length and | ||
* if the elements are equal to one another in the same order | ||
*/ | ||
public static <T> boolean equals(T @NonNull [] a, int aFrom, int aTo, | ||
T @NonNull [] b, int bFrom, int bTo, | ||
@NonNull BiPredicate<T, T> cmp) { | ||
Preconditions.checkFromToIndex(aFrom, aTo, a.length); | ||
Preconditions.checkFromToIndex(bFrom, bTo, b.length); | ||
int aLength = aTo - aFrom; | ||
int bLength = bTo - bFrom; | ||
if (aLength != bLength) { | ||
return false; | ||
} | ||
|
||
for (int i = 0; i < aLength; i++) { | ||
if (!cmp.test(a[aFrom++], b[bFrom++])) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* Copies 'src' and inserts 'value' at position 'index'. | ||
* | ||
* @param src an array | ||
* @param index an index | ||
* @param value a value | ||
* @param <T> the array type | ||
* @return a new array | ||
*/ | ||
public static <T> @NonNull T @NonNull [] copyAdd(@NonNull T @NonNull [] src, int index, T value) { | ||
final T[] dst = copyComponentAdd(src, index, 1); | ||
dst[index] = value; | ||
return dst; | ||
} | ||
|
||
/** | ||
* Copies 'src' and inserts 'values' at position 'index'. | ||
* | ||
* @param src an array | ||
* @param index an index | ||
* @param values the values | ||
* @param <T> the array type | ||
* @return a new array | ||
*/ | ||
public static <T> @NonNull T @NonNull [] copyAddAll(@NonNull T @NonNull [] src, int index, @NonNull T @NonNull [] values) { | ||
final T[] dst = copyComponentAdd(src, index, values.length); | ||
System.arraycopy(values, 0, dst, index, values.length); | ||
return dst; | ||
} | ||
|
||
/** | ||
* Copies 'src' and inserts 'numComponents' at position 'index'. | ||
* <p> | ||
* The new components will have a null value. | ||
* | ||
* @param src an array | ||
* @param index an index | ||
* @param numComponents the number of array components to be added | ||
* @param <T> the array type | ||
* @return a new array | ||
*/ | ||
public static <T> @NonNull T @NonNull [] copyComponentAdd(@NonNull T @NonNull [] src, int index, int numComponents) { | ||
if (index == src.length) { | ||
return Arrays.copyOf(src, src.length + numComponents); | ||
} | ||
@SuppressWarnings("unchecked") final T[] dst = (T[]) Array.newInstance(src.getClass().getComponentType(), src.length + numComponents); | ||
System.arraycopy(src, 0, dst, 0, index); | ||
System.arraycopy(src, index, dst, index + numComponents, src.length - index); | ||
return dst; | ||
} | ||
|
||
/** | ||
* Copies 'src' and removes 'numComponents' at position 'index'. | ||
* | ||
* @param src an array | ||
* @param index an index | ||
* @param numComponents the number of array components to be removed | ||
* @param <T> the array type | ||
* @return a new array | ||
*/ | ||
public static <T> @NonNull T @NonNull [] copyComponentRemove(@NonNull T @NonNull [] src, int index, int numComponents) { | ||
if (index == src.length - numComponents) { | ||
return Arrays.copyOf(src, src.length - numComponents); | ||
} | ||
@SuppressWarnings("unchecked") final T[] dst = (T[]) Array.newInstance(src.getClass().getComponentType(), src.length - numComponents); | ||
System.arraycopy(src, 0, dst, 0, index); | ||
System.arraycopy(src, index + numComponents, dst, index, src.length - index - numComponents); | ||
return dst; | ||
} | ||
|
||
/** | ||
* Copies 'src' and removes one component at position 'index'. | ||
* | ||
* @param src an array | ||
* @param index an index | ||
* @param <T> the array type | ||
* @return a new array | ||
*/ | ||
public static <T> @NonNull T @NonNull [] copyRemove(@NonNull T @NonNull [] src, int index) { | ||
return copyComponentRemove(src, index, 1); | ||
} | ||
|
||
/** | ||
* Copies 'src' and sets 'value' at position 'index'. | ||
* | ||
* @param src an array | ||
* @param index an index | ||
* @param value a value | ||
* @param <T> the array type | ||
* @return a new array | ||
*/ | ||
public static <T> @NonNull T @NonNull [] copySet(@NonNull T @NonNull [] src, int index, T value) { | ||
final T[] dst = Arrays.copyOf(src, src.length); | ||
dst[index] = value; | ||
return dst; | ||
} | ||
} |
100 changes: 100 additions & 0 deletions
100
...src/main/java/org.jhotdraw8.icollection/org/jhotdraw8/icollection/impl/Preconditions.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* | ||
* @(#)Preconditions.java | ||
* Copyright © 2022 The authors and contributors of JHotDraw. MIT License. | ||
*/ | ||
package org.jhotdraw8.icollection.impl; | ||
|
||
|
||
import org.jhotdraw8.annotation.NonNull; | ||
|
||
/** | ||
* Preconditions. | ||
* | ||
* @author Werner Randelshofer | ||
*/ | ||
public class Preconditions { | ||
private Preconditions() { | ||
|
||
} | ||
|
||
/** | ||
* Throws an illegal argument exception with a formatted message | ||
* if the expression is not true. | ||
* | ||
* @param expression an expression | ||
* @param errorMessageTemplate the template for the error message | ||
* @param arguments arguments for the error message | ||
* @throws IllegalArgumentException if expression is not true | ||
*/ | ||
public static void checkArgument(boolean expression, @NonNull String errorMessageTemplate, @NonNull Object... arguments) { | ||
if (!expression) { | ||
throw new IllegalArgumentException(String.format(errorMessageTemplate, arguments)); | ||
} | ||
} | ||
|
||
/** | ||
* Checks if the provided value is in the range {@code [min, max]}. | ||
* | ||
* @param value a value | ||
* @param min the lower bound of the range (inclusive) | ||
* @param max the upper bound of the range (inclusive) | ||
* @param name the name of the value | ||
* @return the value | ||
* @throws IllegalArgumentException if value is not in [min, max]. | ||
*/ | ||
public static int checkValueInRange(int value, int min, int max, String name) { | ||
if (value < min || value >= max) { | ||
throw new IllegalArgumentException(name + ": " + value + " not in range: [" + min + ", " + max + "]."); | ||
} | ||
return value; | ||
} | ||
|
||
/** | ||
* Checks if the provided index is in the range {@code [0, length)}. | ||
* | ||
* @param index an index value | ||
* @param length the size value (exclusive) | ||
* @return the index value | ||
* @throws IndexOutOfBoundsException if index is not in {@code [0, length)}. | ||
*/ | ||
public static int checkIndex(int index, int length) { | ||
if (index < 0 || index >= length) { | ||
throw new IndexOutOfBoundsException("index: " + index + " not in range: [0, " + length + ")."); | ||
} | ||
return index; | ||
} | ||
|
||
/** | ||
* Checks if the provided sub-range {@code [from, to)} is inside the | ||
* range {@code [0, length)}, and whether {@code from <= to}. | ||
* | ||
* @param from the lower bound of the sub-range (inclusive) | ||
* @param to the upper bound of the sub-range (exclusive) | ||
* @param length the upper bound of the range (exclusive) | ||
* @return the from value | ||
* @throws IndexOutOfBoundsException if the sub-range is not in {@code [0, length)}. | ||
*/ | ||
public static int checkFromToIndex(int from, int to, int length) { | ||
if (from < 0 || from > to || to > length) { | ||
throw new IndexOutOfBoundsException("sub-range: [" + from + ", " + to + ") not in range: [0, " + length + ")."); | ||
} | ||
return from; | ||
} | ||
|
||
/** | ||
* Checks if the provided sub-range {@code [from, from+size)} is inside the | ||
* range {@code [0, length)} and whether {@code 0 <= size}. | ||
* | ||
* @param from the lower bound of the sub-range (inclusive) | ||
* @param size the size of the sub-range | ||
* @param length the upper bound of the range (exclusive) | ||
* @return the from value | ||
* @throws IndexOutOfBoundsException if the sub-range is not in {@code [0, length)}. | ||
*/ | ||
public static int checkFromIndexSize(int from, int size, int length) { | ||
if (from < 0 || size < 0 || from + size > length) { | ||
throw new IndexOutOfBoundsException("sub-range: [" + from + ", " + (from + size) + ") not in range: [0, " + length + ")."); | ||
} | ||
return from; | ||
} | ||
} |
Oops, something went wrong.