【问题标题】:equivalent of memcmp() in Java?相当于Java中的memcmp()?
【发布时间】:2009-07-07 02:29:27
【问题描述】:

如果我有两个 byte[] 数组,是否有内置函数来比较它们 ala C 的 memcmp()

【问题讨论】:

    标签: java c posix libc memcmp


    【解决方案1】:

    如果发现 s1 的前 n 个字节分别小于、匹配或大于 s2 的前 n 个字节,则 Memcmp 返回一个 int,小于、等于或大于零。 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;
    }
    

    (编辑) 事实上,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;
    }
    

    【讨论】:

    • return 1和return -1不是颠倒过来了吗?
    【解决方案2】:

    有 Arrays.equals()。

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

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

    【讨论】:

    • 我很好奇有人会在 Java 中终止他们自己的数组
    • 我从未尝试过,但我会假设如果有人在 C 中调用本机方法并使用缓冲区...
    • strcmp 是从哪里来的?问题是关于 memcmp,我在编辑历史中也看不到 strcmp。
    • 来自手册页:“如果发现 s1 的前 n 个字节分别小于、等于或大于零,则 memcmp() 函数返回一个整数匹配,或大于 s2 的前 n 个字节。” Arrays.equals() 没有给出任何指示哪个更大。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      嗯,Arrays.equals() 很好,但不能比较子范围。在这种情况下,还有通过Arrays.listOf() 和后来的.subList() 的路径,但不适用于byte[] 之类的原语。

      实际上没有直接的memcmp() 等价物。这是discussion,我知道它现在处于相同状态(15 年)。大多数“本机”实现可以通过我的选项通过java.nio.ByteBufferwrap() 方法然后equals())来实现。但是代码量有点大。

      对于完全不了解主题的人:memcmp() 以平台相关的方式实现,这种方式非常有效,Java 目前没有任何方法可以实现。至少由于索引范围检查,任何手动循环在性能方面都相去甚远。也许有一天,来自嵌入式 C/C++ 的人会对这个话题感到满意 :-)。

      【讨论】:

      • 加 1 用于提及子范围。在这种情况下,可以将Arrays.copyOfRange()Arrays.equals() 一起使用,但无论如何可能效率不高。
      【解决方案5】:

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          猜你喜欢
          • 2010-12-28
          • 2013-05-09
          • 2014-09-29
          • 2011-01-21
          • 2013-09-10
          • 2021-01-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多