comment comparer le tableau Java Byte []?

91
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));
    }
}

Je ne sais pas pourquoi tous affichent des faux.

Lorsque je lance "java ByteArray", la réponse est "false false false false".

Je pense que a [] est égal à b [] mais la JVM me dit que je me trompe, pourquoi ??

Paresseux
la source
duplication possible de Compare two Byte Arrays? (Java)
Vadzim

Réponses:

191

À utiliser Arrays.equals()si vous souhaitez comparer le contenu réel des tableaux contenant des valeurs de types primitifs (comme byte).

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

À utiliser Arrays.deepEqualspour la comparaison de tableaux contenant des objets.

Lukasz
la source
si j'ai un 'HashMap <byte [], IoBuffer>' et je 'put (a, buffer)' ,,, si je 'print (map.containsKey (b))' il imprime "false", c'est pareil raison????
Lazy
3
@Lazy: Oui, la raison est la même ... vous ne pouvez pas utiliser l'octet brut [] comme clé dans les cartes ... En savoir plus ici: stackoverflow.com/questions/1058149/...
Lukasz
6

Parce qu'ils ne sont pas égaux, c'est-à-dire: ce sont des tableaux différents avec des éléments égaux à l'intérieur.

Essayez d'utiliser Arrays.equals()ou Arrays.deepEquals().

soulcheck
la source
Cela fait partie du non-sens Java: pourquoi utiliser une méthode statique d'une classe différente pour comparer des objets dans une autre classe? C'est-à-dire: pourquoi n'ont-ils pas remplacé la equals()méthode?
U. Windl
3

Comme byte [] est mutable, il est traité comme étant uniquement .equals()s'il s'agit du même objet.

Si vous souhaitez comparer les contenus que vous devez utiliser Arrays.equals(a, b)

BTW: Ce n'est pas la façon dont je le concevrais. ;)

Peter Lawrey
la source
1

avez-vous regardé Arrays.equals()?

Edit: si, selon votre commentaire, le problème utilise un tableau d'octets comme clé HashMap, consultez cette question .

Dan Vinton
la source
si j'ai un 'HashMap <byte [], IoBuffer>' et je 'put (a, buffer)' ,,, si je 'print (map.containsKey (b))' il imprime "false", c'est pareil raison????
Lazy
@Lazy - voir stackoverflow.com/questions/1058149/…
Dan Vinton
1

Si vous essayez d'utiliser le tableau en tant que clé HashMap générique, cela ne fonctionnera pas. Envisagez de créer un objet wrapper personnalisé qui contient le tableau et dont la méthode equals(...)and hashcode(...)renvoie les résultats des méthodes java.util.Arrays. Par exemple...

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;
   }


}

Les objets de cette classe wrapper fonctionneront correctement comme clé pour votre HashMap<MyByteArray, OtherType>et permettront une utilisation propre des méthodes equals(...)et hashCode(...).

Aéroglisseur plein d'anguilles
la source
0

Ils renvoient false car vous testez l'identité d'objet plutôt que l'égalité des valeurs. Cela renvoie false car vos tableaux sont en fait des objets différents en mémoire.

Si vous souhaitez tester l'égalité des valeurs, utilisez les fonctions de comparaison pratiques de java.util.Arrays

par exemple

import java.util.Arrays;

'''''

Arrays.equals(a,b);
Mikera
la source
0

Vous pouvez également utiliser un ByteArrayComparatordepuis Apache Directory . En plus d' égal, il vous permet de comparer si un tableau est plus grand que l'autre.

Andrejs
la source
0

Essayez ceci:

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

Je ne suis pas sûr non plus à ce sujet, mais essayez cela peut-être que cela fonctionne.

Bhavesh Shah
la source
0

pourquoi a [] n'est pas égal à b []? Parce que la equalsfonction est vraiment appelée Byte[]ou l' byte[]est Object.equals(Object obj). Cette fonction compare uniquement l'identification d'objet, ne compare pas le contenu du tableau.

Jack47
la source
0

J'ai cherché un wrapper de tableau qui le rend comparable à une utilisation avec la goyave TreeRangeMap. La classe n'accepte pas le comparateur.

Après quelques recherches, j'ai réalisé que ByteBuffer de JDK a cette fonctionnalité et qu'il ne copie pas le tableau d'origine, ce qui est bien. De plus, vous pouvez comparer plus rapidement avec ByteBuffer :: asLongBuffer 8 octets à la fois (ne copie pas non plus). Par défaut, ByteBuffer :: wrap (byte []) utilise BigEndian, donc la relation d'ordre est la même que la comparaison d'octets individuels.

.

Daneel S. Yaitskov
la source
0

Comparaison d'octets Java,

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
la source
0

Parce que ni ==ni la equals()méthode du tableau ne comparent le contenu; les deux n'évaluent que l'identité de l'objet (le fait ==toujours et equals()n'est pas écrasé, donc la version de Objectest utilisée).

Pour comparer le contenu, utilisez Arrays.equals().

Michael Borgwardt
la source
0

Vous pouvez également utiliser org.apache.commons.lang.ArrayUtils.isEquals ()

RoutesMaps.com
la source
0

Arrays.equalsne suffit pas pour un comparateur, vous ne pouvez pas vérifier que la carte contient les données. Je copie le code depuis Arrays.equals, modifié pour créer un fichier 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
la source
-4

Il existe un moyen plus rapide de le faire:

Arrays.hashCode(arr1) == Arrays.hashCode(arr2)
Nagyatka
la source
2
Par «plus rapide», vous entendez «plus lent».
divegeek