Wie vergleiche ich das Java Byte [] Array?

90
public class ByteArr {

    public static void main(String[] args){
        Byte[] a = {(byte)0x03, (byte)0x00, (byte)0x00, (byte)0x00};
        Byte[] b = {(byte)0x03, (byte)0x00, (byte)0x00, (byte)0x00};
        byte[] aa = {(byte)0x03, (byte)0x00, (byte)0x00, (byte)0x00};
        byte[] bb = {(byte)0x03, (byte)0x00, (byte)0x00, (byte)0x00};

        System.out.println(a);
        System.out.println(b);
        System.out.println(a == b);
        System.out.println(a.equals(b));

        System.out.println(aa);
        System.out.println(bb);
        System.out.println(aa == bb);
        System.out.println(aa.equals(bb));
    }
}

Ich weiß nicht, warum alle falsch drucken.

Wenn ich "java ByteArray" ausführe, lautet die Antwort "false false false false".

Ich denke, das a [] ist gleich b [], aber die JVM sagt mir, dass ich falsch liege, warum ??

Faul
quelle
Mögliches Duplikat von Zwei-Byte-Arrays vergleichen? (Java)
Vadzim

Antworten:

189

Verwenden Arrays.equals()Sie diese Option, wenn Sie den tatsächlichen Inhalt von Arrays vergleichen möchten, die Werte für primitive Typen enthalten (z. B. Byte).

System.out.println(Arrays.equals(aa, bb));

Verwenden Sie Arrays.deepEqualszum Vergleich von Arrays , die Objekte enthalten.

Lukasz
quelle
Wenn ich eine 'HashMap <byte [], IoBuffer>' und i 'put (a, buffer)' ,,, wenn ich 'print (map.containsKey (b))' drucke, ist es das gleiche Grund????
Faul
3
@ Lazy: Ja, der Grund ist der gleiche ... Sie können Raw Byte [] nicht als Schlüssel in Karten verwenden ... Lesen Sie hier mehr: stackoverflow.com/questions/1058149/…
Lukasz
6

Weil sie nicht gleich sind, dh sie sind verschiedene Arrays mit gleichen Elementen.

Versuchen Sie es mit Arrays.equals()oder Arrays.deepEquals().

Soulcheck
quelle
Das ist Teil des Java-Unsinns: Warum eine statische Methode aus einer anderen Klasse verwenden, um Objekte in einer anderen Klasse zu vergleichen? Das heißt: Warum haben sie die equals()Methode nicht überschrieben ?
U. Windl
3

Da Byte [] veränderbar ist, wird es nur .equals()dann als solches behandelt, wenn es dasselbe Objekt ist.

Wenn Sie den Inhalt vergleichen möchten, müssen Sie ihn verwenden Arrays.equals(a, b)

Übrigens: Es ist nicht so, wie ich es entwerfen würde. ;)

Peter Lawrey
quelle
1

haben Sie sehen Arrays.equals()?

Bearbeiten: Wenn das Problem gemäß Ihrem Kommentar ein Byte-Array als HashMap-Schlüssel verwendet, wird diese Frage angezeigt .

Dan Vinton
quelle
Wenn ich eine 'HashMap <byte [], IoBuffer>' und i 'put (a, buffer)' ,,, wenn ich 'print (map.containsKey (b))' drucke, ist es das gleiche Grund????
Faul
@ Lazy - siehe stackoverflow.com/questions/1058149/…
Dan Vinton
1

Wenn Sie versuchen, das Array als generischen HashMap-Schlüssel zu verwenden, funktioniert dies nicht. Erwägen Sie, ein benutzerdefiniertes Wrapper-Objekt zu erstellen, das das Array enthält und dessen equals(...)und hashcode(...)-Methode die Ergebnisse der Methoden java.util.Arrays zurückgibt. Beispielsweise...

import java.util.Arrays;

public class MyByteArray {
   private byte[] data;

   // ... constructors, getters methods, setter methods, etc...


   @Override
   public int hashCode() {
      return Arrays.hashCode(data);
   }

   @Override
   public boolean equals(Object obj) {
      if (this == obj)
         return true;
      if (obj == null)
         return false;
      if (getClass() != obj.getClass())
         return false;
      MyByteArray other = (MyByteArray) obj;
      if (!Arrays.equals(data, other.data))
         return false;
      return true;
   }


}

Objekte dieser Wrapper-Klasse funktionieren gut als Schlüssel für Ihre HashMap<MyByteArray, OtherType>und ermöglichen eine saubere Verwendung von equals(...)und hashCode(...)Methoden.

Luftkissenfahrzeug voller Aale
quelle
0

Sie geben false zurück, weil Sie eher auf Objektidentität als auf Wertgleichheit testen. Dies gibt false zurück, da Ihre Arrays tatsächlich unterschiedliche Objekte im Speicher sind.

Wenn Sie auf Wertgleichheit testen möchten, sollten Sie die praktischen Vergleichsfunktionen in java.util.Arrays verwenden

z.B

import java.util.Arrays;

'''''

Arrays.equals(a,b);
mikera
quelle
0

Sie können auch eine Verwendung ByteArrayComparatorvon Apache Directory . Zusätzlich zu gleich können Sie vergleichen, ob ein Array größer als das andere ist.

Andrejs
quelle
0

Versuchen Sie dies:

boolean blnResult = Arrays.equals(byteArray1, byteArray2);

Ich bin mir auch nicht sicher, aber versuche es, vielleicht funktioniert es.

Bhavesh Shah
quelle
0

warum ist a [] nicht gleich b []? Weil die equalsFunktion wirklich aufgerufen ist Byte[]oder byte[]ist Object.equals(Object obj). Diese Funktion vergleicht nur die Objektidentifikation, nicht den Inhalt des Arrays.

Jack47
quelle
0

Ich habe nach einem Array-Wrapper gesucht, der die Verwendung mit Guava TreeRangeMap vergleichbar macht. Die Klasse akzeptiert keinen Komparator.

Nach einigen Recherchen wurde mir klar, dass ByteBuffer von JDK diese Funktion hat und das ursprüngliche Array nicht kopiert, was gut ist. Darüber hinaus können Sie mit ByteBuffer :: asLongBuffer 8 Bytes gleichzeitig schneller vergleichen (kopiert auch nicht). Standardmäßig verwendet ByteBuffer :: wrap (byte []) BigEndian, sodass die Ordnungsbeziehung der Vergleich einzelner Bytes entspricht.

.

Daneel S. Yaitskov
quelle
0

Java Byte vergleichen,

public static boolean equals(byte[] a, byte[] a2) {
        if (a == a2)
            return true;
        if (a == null || a2 == null)
            return false;

        int length = a.length;
        if (a2.length != length)
            return false;

        for (int i = 0; i < length; i++)
            if (a[i] != a2[i])
                return false;

        return true;
    }
Rakesh Chaudhari
quelle
0

Weil weder ==noch die equals()Methode des Arrays den Inhalt vergleichen; Beide bewerten nur die Objektidentität ( ==immer und equals()nicht überschrieben, daher wird die Version von Objectverwendet).

Verwenden Sie zum Vergleichen des Inhalts Arrays.equals().

Michael Borgwardt
quelle
0

Sie können auch org.apache.commons.lang.ArrayUtils.isEquals () verwenden.

RoutesMaps.com
quelle
0

Arrays.equalsreicht für einen Komparator nicht aus, Sie können nicht überprüfen, ob die Karte die Daten enthält. Ich kopiere den Code von Arrays.equals, geändert, um eine zu erstellen Comparator.

class ByteArrays{
    public static <T> SortedMap<byte[], T> newByteArrayMap() {
        return new TreeMap<>(new ByteArrayComparator());
    }

    public static SortedSet<byte[]> newByteArraySet() {
        return new TreeSet<>(new ByteArrayComparator());
    }

    static class ByteArrayComparator implements Comparator<byte[]> {
        @Override
        public int compare(byte[] a, byte[] b) {
            if (a == b) {
                return 0;
            }
            if (a == null || b == null) {
                throw new NullPointerException();
            }

            int length = a.length;
            int cmp;
            if ((cmp = Integer.compare(length, b.length)) != 0) {
                return cmp;
            }

            for (int i = 0; i < length; i++) {
                if ((cmp = Byte.compare(a[i], b[i])) != 0) {
                    return cmp;
                }
            }

            return 0;
        }
    }
}
wener
quelle
-4

Es gibt einen schnelleren Weg, dies zu tun:

Arrays.hashCode(arr1) == Arrays.hashCode(arr2)
Nagyatka
quelle
2
Mit "schneller" meinen Sie "langsamer".
Divegeek