Вопрос

Если у меня есть два byte[] массивы, есть ли встроенная функция для сравнения их с C memcmp() ?

Это было полезно?

Решение

Есть Arrays.equals().

Я не знаю, действительно ли реализация JVM оптимизирует это, если соответствующая инструкция существует в аппаратном обеспечении, но я сомневаюсь в этом.

Кроме того, если я правильно помню свой C, strcmp работает с нулевым ограничителем (что делает его полезным для строк C), версия Arrays будет сравнивать весь массив, поскольку программисты Java редко обращаются к массивам с нулевым завершением.Однако вы могли бы легко написать свою собственную функцию, если вас волнует нулевой терминатор.

Другие советы

Memcmp возвращает значение int, меньшее, равное или большее нуля, если обнаруживается, что первые n байтов s1 соответственно меньше, совпадают или больше первых n байтов s2.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;
}

В java.util.Массивы.равно(байт[], byte[]) метод - это ваш друг.

Что ж, Arrays.equals() это хорошо, но не позволяет сравнивать поддиапазоны.В этом случае также существует путь через Arrays.listOf() и позже .subList() но не для таких примитивов, как byte[].

На самом деле нет никакого прямого memcmp() эквивалент.Вот Обсуждение и как только я узнаю, что сейчас он находится в том же состоянии (15 лет).Наиболее "родная" реализация могла бы быть достигнута моим вариантом с помощью java.nio.ByteBuffer (wrap() метод, а затем equals()).Но это несколько большой объем кода.

Для людей, которые полностью не разбираются в предмете: memcmp() реализован зависящим от платформы способом, который очень эффективен, и в настоящее время ничто в Java не приближается к нему.Любые ручные циклы очень далеки с точки зрения производительности, по крайней мере, из-за проверок диапазона индексов.Может быть, когда-нибудь люди, пришедшие с embedded C / C ++, будут удовлетворены этой темой :-).

В 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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top