[英]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));
}
}
我不知道为什么他们都打印假。
当我运行“java ByteArray”时,答案是“false false false false”。
我认为a []等于b []但是JVM告诉我我错了,为什么?
如果要比较包含基本类型值(如byte)的数组的实际内容,请使用Arrays.equals()
)。
System.out.println(Arrays.equals(aa, bb));
使用Arrays.deepEquals
比较包含对象的数组。
因为它们不相等,即:它们是内部具有相同元素的不同数组。
尝试使用Arrays.equals()
或Arrays.deepEquals()
。
由于byte []是可变的,如果它是相同的对象,它被视为仅仅是.equals()
。
如果你想比较你必须使用的内容Arrays.equals(a, b)
顺便说一句:这不是我设计它的方式。 ;)
你看过Arrays.equals()
吗?
编辑:如果,根据您的评论,问题是使用字节数组作为HashMap键,然后看到这个问题 。
如果您尝试将该数组用作通用HashMap键,那么这不会起作用。 考虑创建一个包含数组的自定义包装器对象,其equals(...)
和hashcode(...)
方法返回java.util.Arrays方法的结果。 例如...
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;
}
}
这个包装类的对象可以很好地作为HashMap<MyByteArray, OtherType>
的键,并允许干净地使用equals(...)
和hashCode(...)
方法。
您还可以使用Apache Directory中的ByteArrayComparator
。 除了equals之外,它还可以比较一个数组是否大于另一个数组。
为什么a []不等于b []? 因为实际调用Byte[]
或byte[]
equals
函数是Object.equals(Object obj)
。 此函数仅比较对象标识,不比较数组的内容。
我找了一个数组包装器,它可以与guava TreeRangeMap相媲美。 该班不接受比较。
经过一番研究后,我意识到JDK的ByteBuffer有这个功能,它不会复制好的原始数组。 更多的是你可以更快地与ByteBuffer :: asLongBuffer比较8个字节(也不复制)。 默认情况下,ByteBuffer :: wrap(byte [])使用BigEndian,因此顺序关系与比较单个字节相同。
。
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.commons.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;
}
}
}
因为数组的==
和equals()
方法都不比较内容; 两者都只评估对象标识( ==
总是这样,并且不会覆盖equals()
,因此正在使用Object
的版本)。
要比较内容,请使用Arrays.equals()
。
它们返回false,因为您正在测试对象标识而不是值相等。 返回false,因为您的数组实际上是内存中的不同对象。
如果要测试值的相等性,请使用java.util.Arrays中的方便比较函数
例如
import java.util.Arrays;
'''''
Arrays.equals(a,b);
试试这个:
boolean blnResult = Arrays.equals(byteArray1, byteArray2);
我也不确定这一点,但尝试这可能是有效的。
有一种更快的方法:
Arrays.hashCode(arr1) == Arrays.hashCode(arr2)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.