Zwei Byte-Arrays vergleichen? (Java)

95

Ich habe ein Byte-Array mit einer bekannten Binärsequenz. Ich muss bestätigen, dass die Binärsequenz so ist, wie sie sein soll. Ich habe es .equalszusätzlich versucht ==, aber keiner hat funktioniert.

byte[] array = new BigInteger("1111000011110001", 2).toByteArray();
if (new BigInteger("1111000011110001", 2).toByteArray() == array){
    System.out.println("the same");
} else {
    System.out.println("different'");
}
Roger
quelle
Kannst du die Strings einfach direkt vergleichen?
Objekte
1
@Objekte - führende Nullen. Außerdem könnte das String / BigInteger-Zeug nur eine Möglichkeit sein, die Frage des Byte-Array-Vergleichs zu veranschaulichen.
Stephen C
Haben Sie versucht, die compareTo-Methode zu verwenden? Übrigens ==vergleicht primitive Werte nur zu
Ihrer Information
Hier ist eine verwandte Frage zum partiellen Array-Vergleich: stackoverflow.com/questions/16646967/…
Vadzim

Antworten:

164

In Ihrem Beispiel haben Sie:

if (new BigInteger("1111000011110001", 2).toByteArray() == array)

Beim Umgang mit Objekten ==vergleicht Java in Java Referenzwerte . Sie überprüfen, ob der Verweis auf das von zurückgegebene Array mit toByteArray()dem Verweis in übereinstimmt array, der natürlich niemals wahr sein kann. Außerdem werden Array-Klassen nicht überschrieben, .equals()sodass das Verhalten dasjenige ist, bei Object.equals()dem auch nur die Referenzwerte verglichen werden.

Um den Inhalt von zwei Arrays zu vergleichen , werden statische Array-Vergleichsmethoden von der Arrays-Klasse bereitgestellt

byte[] array = new BigInteger("1111000011110001", 2).toByteArray();
byte[] secondArray = new BigInteger("1111000011110001", 2).toByteArray();
if (Arrays.equals(array, secondArray))
{
    System.out.println("Yup, they're the same!");
}
Brian Roach
quelle
64

Schauen Sie sich die statische java.util.Arrays.equals()Methodenfamilie an. Es gibt einen, der genau das macht, was Sie wollen.

Ernest Friedman-Hill
quelle
11

Java überlädt keine Operatoren, daher benötigen Sie normalerweise eine Methode für nicht grundlegende Typen. Probieren Sie die Methode Arrays.equals () aus .

jswolf19
quelle
11

Sie können beide Arrays.equals()und verwenden MessageDigest.isEqual(). Diese beiden Methoden weisen jedoch einige Unterschiede auf.

MessageDigest.isEqual()ist eine zeitkonstante Vergleichsmethode und Arrays.equals()nicht zeitkonstant. Wenn Sie sie in einer Sicherheitsanwendung verwenden, kann dies zu Sicherheitsproblemen führen.

Die Details für den Unterschied können unter Arrays.equals () vs MessageDigest.isEqual () gelesen werden.

PixelsTech
quelle
3

Natürlich ist die akzeptierte Antwort von Arrays.equal (Byte [] zuerst, Byte [] zweitens) korrekt. Ich arbeite gerne auf einer niedrigeren Ebene, konnte jedoch keine effiziente Funktion auf niedriger Ebene finden, um Gleichheitstestbereiche durchzuführen. Ich musste meine eigenen aufschlagen, wenn jemand es braucht:

public static boolean ArraysAreEquals(
 byte[] first,
 int firstOffset,
 int firstLength,
 byte[] second,
 int secondOffset,
 int secondLength
) {
    if( firstLength != secondLength ) {
        return false;
    }

    for( int index = 0; index < firstLength; ++index ) {
        if( first[firstOffset+index] != second[secondOffset+index]) {
            return false;
        }
    }

    return true;
}
Bamaco
quelle
Dies ist eine gute Lösung zum Testen einer Teilmenge der Arrays und nicht des Ganzen. Beachten Sie jedoch, dass Arrays.equals (Byte [], Byte []) so ziemlich genau alles tut, was Sie hier getan haben (außer, dass die beiden Werte effizienter dasselbe Objekt sind und Null-Arrays ordnungsgemäß übergeben werden). Wenn ich die Wahl habe, eine Standardbibliotheksimplementierung zu verwenden, die von der Community unterstützt wird, oder eine benutzerdefinierte Implementierung zu schreiben, die ich für immer unterstützen muss, werde ich mich jedes Mal für die erstere entscheiden.
Tom Dibble
4
Die Antwort ist nützlich für den Anwendungsfall, in dem zwei Arrays vorhanden sind und der Bytebereich von diesen verglichen werden soll, ohne zuvor Kopien der Arrays zu erstellen. Array-Kopien erhöhen den Overhead, fügen Müll hinzu und werden nicht benötigt. Was ich brauchte, war ein Low-Level-Memcmp () im C-Stil, und das passt zu den Anforderungen. Natürlich akzeptiert memcmp () nur ein Längenargument. Diese Funktion ist nah genug.
Bamaco
2

Da ich zwei Arrays für einen Unit-Test vergleichen wollte und zu dieser Antwort kam, dachte ich, ich könnte sie teilen.

Sie können es auch tun mit:

@Test
public void testTwoArrays() {
  byte[] array = new BigInteger("1111000011110001", 2).toByteArray();
  byte[] secondArray = new BigInteger("1111000011110001", 2).toByteArray();

  Assert.assertArrayEquals(array, secondArray);
}

Weitere Informationen finden Sie unter Vergleichen von Arrays in JUnit-Zusicherungen .

Sylhare
quelle