Reputation: 1462
public class ByteArr {
public static void main(String[] args){
Byte[] a = {(byte)0x03, (byte)0x00, (byte)0x00, (byte)0x00};
Byte[] b = {(byte)0x03, (byte)0x00, (byte)0x00, (byte)0x00};
byte[] aa = {(byte)0x03, (byte)0x00, (byte)0x00, (byte)0x00};
byte[] bb = {(byte)0x03, (byte)0x00, (byte)0x00, (byte)0x00};
System.out.println(a);
System.out.println(b);
System.out.println(a == b);
System.out.println(a.equals(b));
System.out.println(aa);
System.out.println(bb);
System.out.println(aa == bb);
System.out.println(aa.equals(bb));
}
}
I do not know why all of them print false.
When I run "java ByteArray", the answer is "false false false false".
I think the a[] equals b[] but the JVM is telling me I am wrong, why??
Upvotes: 127
Views: 163226
Reputation: 12958
As a newer solution, you can use
import org.junit.jupiter.api.Assertions.*
assertArrayEquals(aa,bb);
Upvotes: 0
Reputation: 7770
Arrays.equals
is not enough for a comparator, you can not check the map contain the data. I copy the code from Arrays.equals
, modified to build a Comparator
.
class ByteArrays{
public static <T> SortedMap<byte[], T> newByteArrayMap() {
return new TreeMap<>(new ByteArrayComparator());
}
public static SortedSet<byte[]> newByteArraySet() {
return new TreeSet<>(new ByteArrayComparator());
}
static class ByteArrayComparator implements Comparator<byte[]> {
@Override
public int compare(byte[] a, byte[] b) {
if (a == b) {
return 0;
}
if (a == null || b == null) {
throw new NullPointerException();
}
int length = a.length;
int cmp;
if ((cmp = Integer.compare(length, b.length)) != 0) {
return cmp;
}
for (int i = 0; i < length; i++) {
if ((cmp = Byte.compare(a[i], b[i])) != 0) {
return cmp;
}
}
return 0;
}
}
}
Upvotes: 0
Reputation: 1689
You can also use org.apache.commons.lang.ArrayUtils.isEquals()
Upvotes: 0
Reputation: 346536
Because neither ==
nor the equals()
method of the array compare the contents; both only evaluate object identity (==
always does, and equals()
is not overwritten, so the version from Object
is being used).
For comparing the contents, use Arrays.equals()
.
Upvotes: 1
Reputation: 3510
Java byte compare,
public static boolean equals(byte[] a, byte[] a2) {
if (a == a2)
return true;
if (a == null || a2 == null)
return false;
int length = a.length;
if (a2.length != length)
return false;
for (int i = 0; i < length; i++)
if (a[i] != a2[i])
return false;
return true;
}
Upvotes: 0
Reputation: 6099
I looked for an array wrapper which makes it comparable to use with guava TreeRangeMap. The class doesn't accept comparator.
After some research I realized that ByteBuffer from JDK has this feature and it doesn't copy original array which is good. More over you can compare faster with ByteBuffer::asLongBuffer 8 bytes at time (also doesn't copy). By default ByteBuffer::wrap(byte[]) use BigEndian so order relation is the same as comparing individual bytes.
.
Upvotes: 0
Reputation: 194
why a[] doesn't equals b[]?
Because equals
function really called on Byte[]
or byte[]
is Object.equals(Object obj)
. This functions only compares object identify , don't compare the contents of the array.
Upvotes: 0
Reputation: 1
There's a faster way to do that:
Arrays.hashCode(arr1) == Arrays.hashCode(arr2)
Upvotes: -5
Reputation: 3389
Try for this:
boolean blnResult = Arrays.equals(byteArray1, byteArray2);
I am also not sure about this, but try this may be it works.
Upvotes: 1
Reputation: 27735
You can also use a ByteArrayComparator
from Apache Directory. In addition to equals it lets you compare if one array is greater than the other.
Upvotes: 0
Reputation: 285460
If you're trying to use the array as a generic HashMap key, that's not going to work. Consider creating a custom wrapper object that holds the array, and whose equals(...)
and hashcode(...)
method returns the results from the java.util.Arrays methods. For example...
import java.util.Arrays;
public class MyByteArray {
private byte[] data;
// ... constructors, getters methods, setter methods, etc...
@Override
public int hashCode() {
return Arrays.hashCode(data);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MyByteArray other = (MyByteArray) obj;
if (!Arrays.equals(data, other.data))
return false;
return true;
}
}
Objects of this wrapper class will work fine as a key for your HashMap<MyByteArray, OtherType>
and will allow for clean use of equals(...)
and hashCode(...)
methods.
Upvotes: 1
Reputation: 26769
have you looked at Arrays.equals()
?
Edit: if, as per your comment, the issue is using a byte array as a HashMap key then see this question.
Upvotes: 1
Reputation: 533880
As byte[] is mutable it is treated as only being .equals()
if its the same object.
If you want to compare the contents you have to use Arrays.equals(a, b)
BTW: Its not the way I would design it. ;)
Upvotes: 7
Reputation: 106401
They are returning false because you are testing for object identity rather than value equality. This returns false because your arrays are actually different objects in memory.
If you want to test for value equality should use the handy comparison functions in java.util.Arrays
e.g.
import java.util.Arrays;
'''''
Arrays.equals(a,b);
Upvotes: 0
Reputation: 36777
Cause they're not equal, ie: they're different arrays with equal elements inside.
Try using Arrays.equals()
or Arrays.deepEquals()
.
Upvotes: 10
Reputation: 7662
Use Arrays.equals()
if you want to compare the actual content of arrays that contain primitive types values (like byte).
System.out.println(Arrays.equals(aa, bb));
Use Arrays.deepEquals
for comparison of arrays that contain objects.
Upvotes: 246