como comparar a matriz 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));
    }
}

Não sei por que todos eles imprimem falsos.

Quando executo "java ByteArray", a resposta é "false false false false".

Acho que a [] é igual a b [], mas a JVM está me dizendo que estou errado, por que ??

Preguiçoso
fonte
possível duplicata de Compare two Byte Arrays? (Java)
Vadzim

Respostas:

190

Use Arrays.equals()se quiser comparar o conteúdo real de matrizes que contêm valores de tipos primitivos (como byte).

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

Use Arrays.deepEqualspara comparação de matrizes que contêm objetos.

Lukasz
fonte
se eu tiver um 'HashMap <byte [], IoBuffer>' e eu 'put (a, buffer)' ,,, se eu 'imprimir (map.containsKey (b))' ele imprimir "false", é o mesmo razão????
Preguiçoso
3
@Lazy: Sim, o motivo é o mesmo ... você não pode usar byte bruto [] como chaves em mapas ... Leia mais aqui: stackoverflow.com/questions/1058149/…
Lukasz
6

Porque eles não são iguais, ou seja: eles são arrays diferentes com elementos iguais dentro.

Experimente usar Arrays.equals()ou Arrays.deepEquals().

verificação de alma
fonte
Isso é parte do absurdo Java: por que usar um método estático de uma classe diferente para comparar objetos em outra classe? Isto é: por que eles não substituíram o equals()método?
U. Windl
3

Como o byte [] é mutável, ele é tratado como sendo apenas .equals() for o mesmo objeto.

Se você quiser comparar o conteúdo, deve usar Arrays.equals(a, b)

BTW: Não é a forma como eu o projetaria. ;)

Peter Lawrey
fonte
1

você olhou Arrays.equals()?

Editar: se, de acordo com seu comentário, o problema for usar uma matriz de bytes como uma chave HashMap, consulte esta questão .

Dan Vinton
fonte
se eu tiver um 'HashMap <byte [], IoBuffer>' e eu 'put (a, buffer)' ,,, se eu 'imprimir (map.containsKey (b))', ele imprimirá "false", é o mesmo razão????
Preguiçoso
@Lazy - consulte stackoverflow.com/questions/1058149/…
Dan Vinton
1

Se você está tentando usar o array como uma chave HashMap genérica, isso não vai funcionar. Considere a criação de um objeto de wrapper personalizado que contenha a matriz e cujo método equals(...)e hashcode(...)retorne os resultados dos métodos java.util.Arrays. Por exemplo...

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


}

Os objetos dessa classe de wrapper funcionarão bem como uma chave para o seu HashMap<MyByteArray, OtherType>e permitirão o uso limpo dos métodos equals(...)e hashCode(...).

Hovercraft cheio de enguias
fonte
0

Eles estão retornando false porque você está testando a identidade do objeto em vez de igualdade de valor. Isso retorna falso porque seus arrays são, na verdade, objetos diferentes na memória.

Se você deseja testar a igualdade de valor, deve usar as funções de comparação úteis em java.util.Arrays

por exemplo

import java.util.Arrays;

'''''

Arrays.equals(a,b);
Mikera
fonte
0

Você também pode usar um ByteArrayComparatordo diretório Apache . Além de igual , permite comparar se um array é maior que o outro.

Andrejs
fonte
0

Experimente:

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

Eu também não tenho certeza sobre isso, mas tente fazer isso pode funcionar.

Bhavesh Shah
fonte
0

por que a [] não é igual a b []? Porque a equalsfunção realmente chamada Byte[]ou byte[]é Object.equals(Object obj). Esta função apenas compara a identificação do objeto, não compara o conteúdo do array.

Jack47
fonte
0

Procurei um empacotador de array que o torne comparável ao uso com guava TreeRangeMap. A classe não aceita comparador.

Depois de alguma pesquisa, percebi que o ByteBuffer do JDK tem esse recurso e não copia o array original, o que é bom. Além disso, você pode comparar mais rápido com ByteBuffer :: asLongBuffer 8 bytes por vez (também não copia). Por padrão, ByteBuffer :: wrap (byte []) usa BigEndian, então a relação de ordem é a mesma que comparar bytes individuais.

.

Daneel S. Yaitskov
fonte
0

Java byte compare,

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
fonte
0

Porque nem, ==nem o equals()método do array compara o conteúdo; ambos avaliam apenas a identidade do objeto ( ==sempre faz, e equals()não é sobrescrito, então a versão deObject está sendo usada).

Para comparar o conteúdo, use Arrays.equals().

Michael Borgwardt
fonte
0

Você também pode usar org.apache.commons.lang.ArrayUtils.isEquals ()

RoutesMaps.com
fonte
0

Arrays.equalsnão é suficiente para um comparador, você não pode verificar se o mapa contém os dados. Eu copio o código Arrays.equals, modificado para construir um 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
fonte
-4

Existe uma maneira mais rápida de fazer isso:

Arrays.hashCode(arr1) == Arrays.hashCode(arr2)
Nagyatka
fonte
2
Por "mais rápido" você quer dizer "mais lento".
divegeek