як порівняти масив 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));
    }
}

Я не знаю, чому всі вони друкують неправду.

Коли я запускаю "java ByteArray", відповідь "false false false false".

Я думаю, що a [] дорівнює b [], але JVM каже мені, що я помиляюся, чому ??


Відповіді:


191

Використовуйте, Arrays.equals()якщо ви хочете порівняти фактичний вміст масивів, які містять значення примітивних типів (наприклад, байт).

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

Використовуйте Arrays.deepEqualsдля порівняння масивів, що містять об’єкти.


якщо у мене є 'HashMap <байт [], IoBuffer>' і я 'put (a, buffer)' ,,, якщо я 'print (map.containsKey (b))' це друкує "false", це те саме причина ????
Ледачий

3
@Lazy: Так, причина та сама ... ви не можете використовувати необроблений байт [] як ключі на картах ... Детальніше тут: stackoverflow.com/questions/1058149/…
Лукаш

6

Тому що вони не рівні, тобто: це різні масиви з однаковими елементами всередині.

Спробуйте скористатися Arrays.equals()або Arrays.deepEquals().


Це частина нісенітниці Java: навіщо використовувати статичний метод з іншого класу для порівняння об’єктів в іншому класі? Тобто: чому вони не замінили equals()метод?
У. Віндл,

3

Оскільки байт [] є змінним, він розглядається як лише, .equals()якщо це той самий об'єкт.

Якщо ви хочете порівняти вміст, який вам доведеться використовувати Arrays.equals(a, b)

BTW: Це не так, як я б це спроектував. ;)


1

ти дивився Arrays.equals()?

Змінити: якщо, згідно з вашим коментарем, проблема використовує байтовий масив як ключ HashMap, тоді перегляньте це питання .


якщо у мене є 'HashMap <байт [], IoBuffer>' і я 'put (a, buffer)' ,,, якщо я 'print (map.containsKey (b))' це друкує "false", це те саме причина ????
Ледачий


1

Якщо ви намагаєтеся використовувати масив як загальний ключ HashMap, це не спрацює. Подумайте про те, щоб створити власний об’єкт-обгортку, що містить масив, а чий equals(...)і hashcode(...)метод повертає результати з методів java.util.Arrays. Наприклад...

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


}

Об'єкти цього класу обгортки будуть чудово працювати як ключ для вас HashMap<MyByteArray, OtherType>і дозволять чітко використовувати equals(...)та hashCode(...)методи.


0

Вони повертають значення false, оскільки ви перевіряєте ідентичність об’єкта, а не рівність значень. Це повертає значення false, оскільки ваші масиви насправді є різними об'єктами в пам'яті.

Якщо ви хочете перевірити рівність значень, скористайтеся зручними функціями порівняння в java.util.Arrays

напр

import java.util.Arrays;

'''''

Arrays.equals(a,b);

0

Ви також можете використовувати a ByteArrayComparatorз каталогу Apache . На додаток до дорівнює, це дозволяє порівняти, якщо один масив більший за інший.


0

Спробуйте для цього:

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

Я також не впевнений у цьому, але спробуйте, можливо, це працює.


0

чому a [] не дорівнює b []? Оскільки equalsфункція дійсно задіяна Byte[]або byte[]є Object.equals(Object obj). Ця функція порівнює лише ідентифікацію об’єкта, не порівнює вміст масиву.


0

Я шукав обгортку масиву, що робить її порівнянною для використання з гуавою TreeRangeMap. Клас не приймає компаратор.

Після деяких досліджень я зрозумів, що ByteBuffer від JDK має цю функцію, і він не копіює оригінальний масив, що добре. Більше того, ви можете швидше порівняти з ByteBuffer :: asLongBuffer 8 байт за раз (також не копіює). За замовчуванням ByteBuffer :: wrap (байт []) використовує BigEndian, тож відношення порядку таке саме, як порівняння окремих байтів.

.


0

Порівняння байтів 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;
    }

0

Оскільки ні ==ані equals()метод масиву не порівнюють вміст; обидва лише оцінюють ідентичність об’єкта ( ==завжди робить це і equals()не перезаписується, тому використовується версія з Object).

Для порівняння вмісту використовуйте Arrays.equals().



0

Arrays.equalsдля компаратора недостатньо, ви не можете перевірити, чи містить карта дані. Я копіюю код Arrays.equals, модифікований для створення 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;
        }
    }
}

-4

Існує більш швидкий спосіб зробити це:

Arrays.hashCode(arr1) == Arrays.hashCode(arr2)

2
Під "швидше" ви маєте на увазі "повільніше".
divegeek
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.