Reputation: 165
I need to compare the first n bytes of two different java byte[] arrays. There is the Arrays equals() function but that tests the length of the arrays first and the whole of both arays after and my arrays are different lengths so that's no good.
Any ideas apart from writing my own loop by hand ?
Thanks,
Upvotes: 4
Views: 5749
Reputation: 26210
Here is more a performant solution using java.nio.ByteBuffer.wrap() that avoids intermediate copy operations:
ByteBuffer.wrap(array1, 0, n).equals(ByteBuffer.wrap(array2, 0, n));
Via java.util.Arrays.equals() with limited length.
Upvotes: 4
Reputation: 8246
Why would you not want to write your own loop by hand? You could just just Arrays to copy out a subset then use it again to compare:-
byte[] a1 = Arrays.copyOfRange(array1, 0, n);
byte[] a2 = Arrays.copyOfRange(array2, 0, n);
boolean equal = Arrays.equals(a1, a2);
If efficiency is a concern then System.arraycopy is a faster but more verbose way of copying arrays.
If efficiency is really a concern and verbosity isn't then the loop is probably the best way.
boolean matched = true;
for (int i=0; i<n; i++){
if (array1[i] != array2[i]) {
matched = false;
break;
}
}
This is because you can stop searching as soon as you see an unmatched byte. If the first byte doesn't match and we are comparing 100 bytes, in the first solution, in the background we are copying 2 lots of 100 bytes, creating two arrays of 100 bytes then comparing 100 sets of bytes, although it will stop at the first one. In the loop this is one iteration through the loop, the mismatch is spotted, flagged and we're done.
Java 8 (UPDATE)
The same thing as above can be done in Java 8 syntax more concisely by creating a Stream of the index numbers to compare (using IntStream) and doing an allMatch on the stream using a Predicate that compares both arrays at each index in the stream, like so:-
//Both arrays must match at all indices between 0 and n
boolean matched = IntStream.range(0, n).allMatch(i -> array1[i] == array2[i]);
//...Of course if you are comparing non simple types, you would need to use equals()
Upvotes: 7
Reputation: 8202
You could copy the first n elements of each array into new arrays, and use Arrays.equals() on those.
byte[] a = {1, 2, 3, 4};
byte[] b = {1, 2, 3, 4, 5, 6};
byte[] aCopy = new byte[3];
System.arraycopy(a, 0, aCopy, 0, aCopy.length);
byte[] bCopy = new byte[3];
System.arraycopy(b, 0, bCopy, 0, bCopy.length);
boolean equal = Arrays.equals(aCopy, bCopy);
Verbose, but it'll do what you want. Alternatively, just loop from 0..n
boolean equal = true;
for (int i = 0; equal && i < 3; i++) {
equal = a[i] == b[i];
}
Upvotes: 2