how to compare the Java Byte[] array?

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??

146115 次浏览

如果要比较包含基本类型值(如字节)的数组的实际内容,请使用 Arrays.equals()

System.out.println(Arrays.equals(aa, bb));

使用 Arrays.deepEquals比较包含对象的数组。

因为它们不相等,即: 它们是不同的数组,内部元素相等。

Try using Arrays.equals() or Arrays.deepEquals().

你看过 Arrays.equals()了吗?

编辑: 如果根据您的注释,问题是使用字节数组作为 HashMap 键,那么请参见 这个问题

因为数组的 ==equals()方法都不比较内容; 它们都只评估对象标识(==总是这样做,而且 equals()没有被覆盖,所以使用了来自 Object的版本)。

For comparing the contents, use Arrays.equals().

它们返回 false,因为您正在测试对象标识而不是值相等性。这将返回 false,因为您的数组实际上是内存中的不同对象。

如果要测试值相等性,应该使用 Java.util. 数组中方便的比较函数

例如:。

import java.util.Arrays;


'''''


Arrays.equals(a,b);

因为 byte []是可变的,所以如果它是同一个对象,那么它只被视为 .equals()

如果你想比较的内容,你必须使用 Arrays.equals(a, b)

顺便说一句: 这不是我想要的设计方式

试试这个:

boolean blnResult = Arrays.equals(byteArray1, byteArray2);

我也不确定这一点,但尝试这可能是它的工程。

如果您试图使用数组作为一般的 HashMap 键,那是不会起作用的。考虑创建一个自定义包装器对象,该对象保存数组,其 equals(...)hashcode(...)方法返回 java.util 的结果。数组方法。比如说..。

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.

您还可以使用来自 Apache DirectoryByteArrayComparator。除了 等于之外,它还允许比较一个数组是否为 greater

还有一个更快的方法:

Arrays.hashCode(arr1) == Arrays.hashCode(arr2)

为什么 a []不等于 b []? 因为在 Byte[]byte[]上实际调用的 equals函数是 Object.equals(Object obj)。这个函数只比较对象标识,不比较数组的内容。

I looked for an array wrapper which makes it comparable to use with guava TreeRangeMap. The class doesn't accept comparator.

经过一些研究,我认识到,字节缓冲从 JDK 有这个功能,它不复制原来的数组,这是很好的。 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.

.

Java 字节比较,

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;
}

还可以使用 org.apache.commans.lang. ArrayUtils.isEquals ()

Arrays.equals对于比较器来说是不够的,你不能检查包含数据的地图。我从 Arrays.equals复制代码,修改为构建 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;
}
}
}