【发布时间】:2011-07-03 17:54:32
【问题描述】:
我有一个带有 byte[] 键的哈希图。我想通过 TreeMap 对其进行排序。
实现字典顺序比较器最有效的方法是什么?
【问题讨论】:
标签: java sorting collections map compare
我有一个带有 byte[] 键的哈希图。我想通过 TreeMap 对其进行排序。
实现字典顺序比较器最有效的方法是什么?
【问题讨论】:
标签: java sorting collections map compare
您可以使用比较器来比较数组中每个字节的 Character.toLowerCase()(假设 byte[] 为 ASCII 格式),否则您需要自己进行字符解码或使用new String(bytes, charSet).toLowerCase()但这不太可能有效。
【讨论】:
我假设问题只是“字节与字节”比较。处理数组很简单,所以我不会介绍它。关于字节与字节,我的第一个想法是这样做:
public class ByteComparator implements Comparator<byte> {
public int compare(byte b1, byte b2) {
return new Byte(b1).compareTo(b2);
}
}
但这不是按字典顺序排列的:0xFF(-1 的有符号字节)将被认为小于 0x00,而按字典顺序排列则更大。我认为这应该可以解决问题:
public class ByteComparator implements Comparator<byte> {
public int compare(byte b1, byte b2) {
// convert to unsigned bytes (0 to 255) before comparing them.
int i1 = b1 < 0 ? 256 + b1 : b1;
int i2 = b2 < 0 ? 256 + b2 : b2;
return i2 - i1;
}
}
可能在 Apache 的 commons-lang 或 commons-math 库中有一些东西可以做到这一点,但我不知道。
【讨论】:
使用Guava,您可以使用以下任一种:
UnsignedBytes 比较器似乎有一个使用Unsafe 的优化形式,它会尽可能使用它。代码中的注释表明它可能至少是普通 Java 实现的两倍。
【讨论】:
在 Apache Hbase 中找到了这段不错的代码:
public int compare(byte[] left, byte[] right) {
for (int i = 0, j = 0; i < left.length && j < right.length; i++, j++) {
int a = (left[i] & 0xff);
int b = (right[j] & 0xff);
if (a != b) {
return a - b;
}
}
return left.length - right.length;
}
【讨论】:
UnsignedBytes.lexicographicalComparator()的非优化版本所做的。
i 和j,而一个变量就足够了。此外,存储 int length = Math.min(left.length, right.length) 并比较 i < length 将改善大型数组的这一点