java - ByteBuffer - CompareTo 方法可能会出现分歧

标签 java nio bytebuffer compareto

基于文章here ,处理负数时,ByteBuffers 上的compareTo 方法可能无法正常工作

bytes in Java are signed, contrary to what one typically expects. What is easy to miss
though, is the fact that this affects ByteBuffer.compareTo() as well. The Java API
documentation for that method reads:

"Two byte buffers are compared by comparing their sequences of remaining elements 
lexicographically, without regard to the starting position of each sequence within its
corresponding buffer."

A quick reading might lead one to believe the result is what you would typically expect, 
but of course given the definition of a byte in Java, this is not the case. The result 
is that the order of byte buffers that contains values with the highest order bit set,   
will diverge from what you may be expecting.

我尝试了几个将负值放入缓冲区的示例,并与正值进行比较,结果总是没问题。这篇文章谈论的是当我们例如当整数 -1 存储为 100000...001 时读取二进制数据,这会导致问题吗?

最佳答案

文章声称 ByteBuffer 包含设置了高位的字节(即值在 0x800xFF 范围内的字节) ) 与另一个缓冲区中的相应字节相比时将被视为值。换句话说,每个字节都被视为一个 8 位有符号整数。因此,您应该预期 0x90 的字节值将小于 0x30 的字节值。

至少,考虑到 Java 中 byte 值的标准行为,这是理论上的。在实践中,我希望字节将作为 8 位无符号整数进行比较,因此 0x90 的字节将比较大于 0x30 的字节。

这完全取决于如何解释“词典顺序”一词。例如,如果每个字节代表一个 8 位字符代码,那么它在逻辑上应该被视为无符号值(无论 Java 通常如何处理 byte 对象)。

所以它归结为两个ByteBuffers的比较是如何实际实现的。一种方法是将字节视为 Java 有符号整数,如下所示:

// Note: Code has be simplified for brevity
int compare(byte[] buf1, byte[] buf2)
{
    ...
    for (int i = 0;  i < buf1.length  &&  i < buf2.length;  i++)
    {
        int cmp = buf1[i] - buf2[i];        // Signed arithmetic
        if (cmp != 0)
            return cmp;
    }
    return (buf1.length - buf2.length);
}

另一种方法是将字节视为无符号整数,它使用稍微不同的算术进行比较:

        int cmp = (buf1[i] & 0xFF) - (buf2[i] & 0xFF);  // Unsigned arithmetic

正如我上面所说,我希望大多数实现都使用第二种方法,而无需给出“字典顺序”的任何具体定义。

关于java - ByteBuffer - CompareTo 方法可能会出现分歧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22254758/

相关文章:

java - 获取Eclipse E4的GUI组件

java - 当写入数据多于读取数据时,NIO 会失败

java - 为什么ByteBuffer.allocate()和ByteBuffer.allocateDirect()之间的奇异性能曲线差异

java - 为什么这两个字节操作不相等?

c# - 字节数组到图像的转换

java - 如何分析 Java 中的线程转储以最大限度地减少高 CPU 使用率

java - 如何通过Selenium从下载弹出框中保存文件?

Java 8 : read files with special characters in name

java - 将两个 byteBuffer 连接成一个

java - 让轨迹球在Android java中按代码发光