Подтвердить что ты не робот

Компаратор Java для массива байтов (лексикографический)

У меня есть hashmap с байтовыми [] клавишами. Я хотел бы отсортировать его через TreeMap.

Каков наиболее эффективный способ реализации компаратора для лексикографического порядка?

4b9b3361

Ответ 1

Используя Guava, вы можете использовать любой из:

Компаратор UnsignedBytes, по-видимому, имеет оптимизированную форму, используя Unsafe, который он использует, если это возможно. Комментарии в коде указывают, что он может быть как минимум в два раза быстрее обычной реализации Java.

Ответ 2

Нашел этот приятный фрагмент кода в 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;
    }

Ответ 3

Я предполагаю, что проблема заключается только в сравнении с байтом и байтом. Работа с массивами проста, поэтому я не буду ее закрывать. Что касается байта и байт, то я сначала подумал об этом:

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, но я этого не знаю.

Ответ 4

Вы можете использовать компаратор, который компилирует Character.toLowerCase() каждого из байтов в массиве (Предполагая, что байт [] находится в ASCII), если вам не нужно будет выполнять декодирование символов самостоятельно или использовать new String(bytes, charSet).toLowerCase() но это вряд ли будет эффективным.