Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion src/main/java/org/apache/commons/lang3/ArrayUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4265,6 +4265,9 @@ public static int lastIndexOf(final double[] array, final double valueToFind, fi
* @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
*/
public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex) {
if (Double.isNaN(valueToFind)) {
return lastIndexOfNaN(array, startIndex);
}
if (isEmpty(array) || startIndex < 0) {
return INDEX_NOT_FOUND;
}
Expand Down Expand Up @@ -4296,6 +4299,9 @@ public static int lastIndexOf(final double[] array, final double valueToFind, in
* @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
*/
public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
if (Double.isNaN(valueToFind)) {
return lastIndexOfNaN(array, startIndex);
}
if (isEmpty(array) || startIndex < 0) {
return INDEX_NOT_FOUND;
}
Expand Down Expand Up @@ -4347,8 +4353,10 @@ public static int lastIndexOf(final float[] array, final float valueToFind, int
if (startIndex >= array.length) {
startIndex = array.length - 1;
}
final boolean searchNaN = Float.isNaN(valueToFind);
for (int i = startIndex; i >= 0; i--) {
if (valueToFind == array[i]) {
final float element = array[i];
if (valueToFind == element || searchNaN && Float.isNaN(element)) {
return i;
}
}
Expand Down Expand Up @@ -4535,6 +4543,24 @@ public static int lastIndexOf(final short[] array, final short valueToFind, int
return INDEX_NOT_FOUND;
}

/**
* Finds the last index of the NaN value in a double array.
* @param array the array to traverse backwards for NaN, may be {@code null}.
* @param startIndex the start index to traverse backwards from.
* @return the last index of the NaN value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
*/
private static int lastIndexOfNaN(final double[] array, final int startIndex) {
if (isEmpty(array) || startIndex < 0) {
return INDEX_NOT_FOUND;
}
for (int i = Math.min(startIndex, array.length - 1); i >= 0; i--) {
if (Double.isNaN(array[i])) {
return i;
}
}
return INDEX_NOT_FOUND;
}

/**
* Maps elements from an array into elements of a new array of a given type, while mapping old elements to new elements.
*
Expand Down
38 changes: 38 additions & 0 deletions src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1824,6 +1824,27 @@ void testLastIndexOfDouble() {
assertEquals(-1, ArrayUtils.lastIndexOf(array, 99));
}

@Test
void testLastIndexOfDoubleNaN() {
final double[] array = { Double.NaN, Double.NEGATIVE_INFINITY, Double.NaN, Double.POSITIVE_INFINITY };
assertEquals(2, ArrayUtils.lastIndexOf(array, Double.NaN));
assertEquals(2, ArrayUtils.lastIndexOf(array, Double.NaN, (double) 0));
assertEquals(0, ArrayUtils.lastIndexOf(array, Double.NaN, 1));
assertEquals(0, ArrayUtils.lastIndexOf(array, Double.NaN, 1, (double) 0));
assertEquals(-1, ArrayUtils.lastIndexOf(array, Double.NaN, -1));
}

@Test
void testLastIndexOfDoubleInfinity() {
final double[] array = { Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY };
assertEquals(2, ArrayUtils.lastIndexOf(array, Double.POSITIVE_INFINITY));
assertEquals(3, ArrayUtils.lastIndexOf(array, Double.NEGATIVE_INFINITY));
assertEquals(0, ArrayUtils.lastIndexOf(array, Double.POSITIVE_INFINITY, 1));
assertEquals(1, ArrayUtils.lastIndexOf(array, Double.NEGATIVE_INFINITY, 2));
assertEquals(2, ArrayUtils.lastIndexOf(array, Double.POSITIVE_INFINITY, array.length, (double) 0));
assertEquals(1, ArrayUtils.lastIndexOf(array, Double.NEGATIVE_INFINITY, 2, (double) 0));
}

@Test
void testLastIndexOfDoubleTolerance() {
double[] array = null;
Expand Down Expand Up @@ -1884,6 +1905,23 @@ void testLastIndexOfFloat() {
assertEquals(-1, ArrayUtils.lastIndexOf(array, 99));
}

@Test
void testLastIndexOfFloatNaN() {
final float[] array = { Float.NaN, Float.NEGATIVE_INFINITY, Float.NaN, Float.POSITIVE_INFINITY };
assertEquals(2, ArrayUtils.lastIndexOf(array, Float.NaN));
assertEquals(0, ArrayUtils.lastIndexOf(array, Float.NaN, 1));
assertEquals(-1, ArrayUtils.lastIndexOf(array, Float.NaN, -1));
}

@Test
void testLastIndexOfFloatInfinity() {
final float[] array = { Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY };
assertEquals(2, ArrayUtils.lastIndexOf(array, Float.POSITIVE_INFINITY));
assertEquals(3, ArrayUtils.lastIndexOf(array, Float.NEGATIVE_INFINITY));
assertEquals(0, ArrayUtils.lastIndexOf(array, Float.POSITIVE_INFINITY, 1));
assertEquals(1, ArrayUtils.lastIndexOf(array, Float.NEGATIVE_INFINITY, 2));
}

@Test
void testLastIndexOfFloatWithStartIndex() {
float[] array = null;
Expand Down
Loading