如果我有两个byte[]
数组,是否有内置函数可以像C语言的memcmp()
一样进行比较?
Memcmp函数返回一个int类型的值,如果s1的前n个字节小于s2的前n个字节,则返回小于零的值,如果相等,则返回零,如果大于,则返回大于零的值。而Equals函数则返回一个布尔值。这两个函数不同。此外,memcmp是将字节作为无符号字符进行比较。
我认为以下内容可以起到作用:
public int memcmp(byte b1[], byte b2[], int sz){
for(int i = 0; i < sz; i++){
if(b1[i] != b2[i]){
if(b1[i] >= 0 && b2[i] >= 0)
return b1[i] - b2[i];
if(b1[i] < 0 && b2[i] >= 0)
return 1;
if(b2[i] < 0 && b1[i] >= 0)
return -1;
if(b1[i] < 0 && b2[i] < 0){
byte x1 = (byte) (256 + b1[i]);
byte x2 = (byte) (256 + b2[i]);
return x1 - x2;
}
}
}
return 0;
}
public static int memcmp(byte b1[], byte b2[], int sz){
for(int i = 0; i < sz; i++){
if(b1[i] != b2[i]){
if((b1[i] >= 0 && b2[i] >= 0)||(b1[i] < 0 && b2[i] < 0))
return b1[i] - b2[i];
if(b1[i] < 0 && b2[i] >= 0)
return 1;
if(b2[i] < 0 && b1[i] >=0)
return -1;
}
}
return 0;
}
有一个Arrays.equals()方法。
我不知道JVM实现是否会优化这个方法,如果硬件上存在相应的指令,但我对此表示怀疑。
另外,如果我记得我的C语言正确,strcmp函数可以比较到空终止符(使其对于C字符串很有用),而Arrays版本将比较整个数组,因为Java程序员很少使用空终止数组。如果您关心空终止符,您可以轻松地编写自己的函数。
Arrays.equals()
方法很好用,但无法比较子范围。在这种情况下,可以使用Arrays.listOf()
和.subList()
方法,但对于像byte[]
这样的原始类型则不适用。
实际上,并没有直接等价于memcmp()
的方法。在这里有一篇讨论,就我所知,它至今仍处于同样的状态(15年了)。大多数“本地”实现可以通过java.nio.ByteBuffer
(使用wrap()
方法然后equals()
)来实现。但这需要写相当多的代码。
对于完全不了解此主题的人:memcmp()
是以平台相关的方式实现的,非常高效,目前在Java中没有任何方法能够与之媲美。任何手动循环都远远落后于性能,至少因为索引范围检查。也许某一天,那些从嵌入式C / C++转来的人会对此感到满意 :-)
Arrays.copyOfRange()
和Arrays.equals()
,但可能不太有效率。 - Ciro Santilli OurBigBook.com[Arrays.equals][1]
[1]:{{link1:http://java.sun.com/j2se/1.5.0/docs/api/java/util/Arrays.html#equals(byte[]}}, byte [])
private static int memcmp(byte[] a, byte[] b, int sz) {
for (int i = 0; i < sz; i++) {
if (a[i] != b[i]) {
return Byte.toUnsignedInt(a[i]) - Byte.toUnsignedInt(b[i]);
}
}
return 0;
}