相当于Java中的memcmp()?

问题描述 投票:0回答:7

如果我有两个

byte[]
数组,是否有一个内置函数可以将它们与 C 的
memcmp()
进行比较?

java c posix libc memcmp
7个回答
7
投票

如果发现 s1 的前 n 个字节分别小于、匹配或大于 s2 的前 n 个字节,则 Memcmp 返回一个 int,小于、等于或大于零。等于返回一个布尔值。这不是同一个功能。此外,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;
}

(编辑) 事实上,2的补码部分并不是必须的:

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

4
投票

有Arrays.equals()。

我不知道如果硬件中存在相应的指令,JVM 实现是否真的对此进行了优化,但我对此表示怀疑。

另外,如果我没记错的话,strcmp 会处理一个空终止符(使其对 C 字符串很有用),数组版本将比较整个数组,因为 Java 程序员很少为空终止数组而烦恼。不过,如果您关心空终止符,您可以轻松编写自己的函数。


4
投票

java.util.Arrays.equals(byte[], byte[]) 方法是你的朋友。


2
投票

嗯,

Arrays.equals()
很好,但无法比较子范围。在这种情况下,还有通过
Arrays.listOf()
和后来的
.subList()
的路径,但不适用于像
byte[]
这样的基元。

实际上没有直接的

memcmp()
等价物。这是讨论,据我所知,现在(15 年)处于相同的状态。大多数“本机”实现可以通过我的选择通过
java.nio.ByteBuffer
wrap()
方法,然后
equals()
)来实现。但代码量有点大。

对于完全不理解主题的人:

memcmp()
是以平台相关的方式实现的,这是非常有效的,目前Java中没有任何东西可以接近它。至少由于索引范围检查,任何手动周期在性能方面都相去甚远。也许有一天,来自嵌入式 C/C++ 的人会对这个主题感到满意:-)。



0
投票

在 Java 8 中,如果您可以将字节视为无符号值,这就是 C/C++ memcmp 实际所做的:

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

0
投票

自 Java 9 起,每个基本数组类型和 Arrays.compare

/泛型 
Object 都有
T
。这可能不如 
memcmp
那么快,但是 它在 OpenJDK 9+103 中针对原始数组进行了矢量化。因此,它可能比简单地循环数组并在 Java 级别进行比较的实现要快。

© www.soinside.com 2019 - 2024. All rights reserved.