эквивалент memcmp() в Java?
Вопрос
Если у меня есть два 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 ++, будут удовлетворены этой темой :-).
[Массивы.равно][1]
[1]: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Arrays.html#equals (байт[], байт[])
В 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;
}