Add ArrayUtils.startsWith()

This commit is contained in:
Gary D. Gregory 2025-01-05 09:14:36 -05:00
parent 4d77a45601
commit ef3d5d93a3
3 changed files with 65 additions and 0 deletions

View File

@ -87,6 +87,7 @@ The <action> type attribute can be add,update,fix,remove.
<action type="add" dev="ggregory" due-to="Gary Gregory">Add SystemUtils.IS_OS_MAC_OSX_SEQUOIA.</action> <action type="add" dev="ggregory" due-to="Gary Gregory">Add SystemUtils.IS_OS_MAC_OSX_SEQUOIA.</action>
<action type="add" dev="ggregory" due-to="Gary Gregory">Add BasicThreadFactory.builder() and deprecate BasicThreadFactory.Builder().</action> <action type="add" dev="ggregory" due-to="Gary Gregory">Add BasicThreadFactory.builder() and deprecate BasicThreadFactory.Builder().</action>
<action type="add" dev="ggregory" due-to="Gary Gregory">Add BasicThreadFactory.daemon().</action> <action type="add" dev="ggregory" due-to="Gary Gregory">Add BasicThreadFactory.daemon().</action>
<action type="add" dev="ggregory" due-to="Gary Gregory">Add ArrayUtils.startsWith.</action>
<!-- UPDATE --> <!-- UPDATE -->
<action type="update" dev="ggregory" due-to="Gary Gregory, Dependabot">Bump org.apache.commons:commons-parent from 73 to 78 #1267, #1277, #1283, #1288, #1302.</action> <action type="update" dev="ggregory" due-to="Gary Gregory, Dependabot">Bump org.apache.commons:commons-parent from 73 to 78 #1267, #1277, #1283, #1288, #1302.</action>
<action type="update" dev="ggregory" due-to="Gary Gregory, Dependabot">[site] Bump org.codehaus.mojo:taglist-maven-plugin from 3.1.0 to 3.2.1 #1300.</action> <action type="update" dev="ggregory" due-to="Gary Gregory, Dependabot">[site] Bump org.codehaus.mojo:taglist-maven-plugin from 3.1.0 to 3.2.1 #1300.</action>

View File

@ -7842,6 +7842,41 @@ public class ArrayUtils {
} }
} }
/**
* Tests whether the given data array starts with an expected array, for example, signature bytes.
* <p>
* If both arrays are null, the method returns true. The method return false when one array is null and the other not.
* </p>
*
* @param data The data to search, maybe larger than the expected data.
* @param expected The expected data to find.
* @return whether a match was found.
* @since 3.18.0
*/
public static boolean startsWith(final byte[] data, final byte[] expected) {
if (data == expected) {
return true;
}
if (data == null || expected == null) {
return false;
}
final int dataLen = data.length;
if (expected.length > dataLen) {
return false;
}
if (expected.length == dataLen) {
// delegate to Arrays.equals() which has optimizations on Java > 8
return Arrays.equals(data, expected);
}
// Once we are on Java 9+ we can delegate to Arrays here as well (or not).
for (int i = 0; i < expected.length; i++) {
if (data[i] != expected[i]) {
return false;
}
}
return true;
}
/** /**
* Produces a new {@code boolean} array containing the elements * Produces a new {@code boolean} array containing the elements
* between the start and end indices. * between the start and end indices.

View File

@ -31,6 +31,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import java.util.BitSet; import java.util.BitSet;
import java.util.Collections; import java.util.Collections;
@ -5176,6 +5177,34 @@ public class ArrayUtilsTest extends AbstractLangTest {
} }
} }
@Test
public void testStartsWith() {
// edge cases
assertTrue(ArrayUtils.startsWith(null, null));
assertFalse(ArrayUtils.startsWith(ArrayUtils.EMPTY_BYTE_ARRAY, null));
assertFalse(ArrayUtils.startsWith(null, ArrayUtils.EMPTY_BYTE_ARRAY));
assertTrue(ArrayUtils.startsWith(ArrayUtils.EMPTY_BYTE_ARRAY, ArrayUtils.EMPTY_BYTE_ARRAY));
assertTrue(ArrayUtils.startsWith(new byte[0], new byte[0]));
// normal cases
assertTrue(ArrayUtils.startsWith(new byte[10], new byte[10]));
assertTrue(ArrayUtils.startsWith(new byte[10], new byte[9]));
assertTrue(ArrayUtils.startsWith(new byte[10], new byte[1]));
final byte[] sig = "Signature".getBytes(StandardCharsets.US_ASCII);
final byte[] data = new byte[1024];
// data is 0
assertFalse(ArrayUtils.startsWith(data, sig));
// data is 1 short for expected at the end
System.arraycopy(sig, 0, data, 0, sig.length - 1);
assertFalse(ArrayUtils.startsWith(data, sig));
// data is mimatched at the start
System.arraycopy(sig, 0, data, 0, sig.length);
data[0] = 0;
assertFalse(ArrayUtils.startsWith(data, sig));
// data is as expected
System.arraycopy(sig, 0, data, 0, sig.length);
assertTrue(ArrayUtils.startsWith(data, sig));
}
@Test @Test
public void testSubarrayBoolean() { public void testSubarrayBoolean() {
final boolean[] nullArray = null; final boolean[] nullArray = null;