У меня есть hashmap с байтовыми [] клавишами. Я хотел бы отсортировать его через TreeMap.
Каков наиболее эффективный способ реализации компаратора для лексикографического порядка?
У меня есть hashmap с байтовыми [] клавишами. Я хотел бы отсортировать его через TreeMap.
Каков наиболее эффективный способ реализации компаратора для лексикографического порядка?
Используя 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;
}
Я предполагаю, что проблема заключается только в сравнении с байтом и байтом. Работа с массивами проста, поэтому я не буду ее закрывать. Что касается байта и байт, то я сначала подумал об этом:
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, но я этого не знаю.
Вы можете использовать компаратор, который компилирует Character.toLowerCase() каждого из байтов в массиве (Предполагая, что байт [] находится в ASCII), если вам не нужно будет выполнять декодирование символов самостоятельно или использовать new String(bytes, charSet).toLowerCase()
но это вряд ли будет эффективным.