Java Byte [] dizisi nasıl karşılaştırılır?


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

Neden hepsinin yanlış yazdığını bilmiyorum.

"Java ByteArray" ı çalıştırdığımda, yanıt "yanlış yanlış yanlış yanlış" oluyor.

Sanırım a [] eşittir b [] ama JVM bana hatalı olduğumu söylüyor, neden ??



Arrays.equals çalışır. Burada çevrimiçi çalıştırın ve kontrol edin onecompiler.com/java/3wc4ec2su
karthikdivi

Yanıtlar:


196

Arrays.equals()İlkel tür değerleri (bayt gibi) içeren dizilerin gerçek içeriğini karşılaştırmak istiyorsanız kullanın .

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

Arrays.deepEqualsNesneleri içeren dizilerin karşılaştırması için kullanın .


Bir 'HashMap <byte [], IoBuffer>' varsa ve '(a, buffer)' koyarsam ,,, eğer 'print (map.containsKey (b))' i 'false' yazdırırsam, aynı mı sebep ????
Tembel

3
@Lazy: Evet, nedeni aynı ... haritalarda anahtar olarak ham baytı [] kullanamazsınız ... Daha fazlasını buradan okuyun: stackoverflow.com/questions/1058149/…
Lukasz

7

Çünkü eşit değiller, yani: içinde eşit elemanlara sahip farklı diziler.

Arrays.equals()Veya kullanmayı deneyin Arrays.deepEquals().


Bu Java saçmalığının bir parçasıdır: Neden başka bir sınıftaki nesneleri karşılaştırmak için farklı bir sınıftan statik bir yöntem kullanasınız? Yani: Neden equals()yöntemi geçersiz kılmadılar?
U. Windl

3

Bayt [] değiştirilebilir olduğundan, yalnızca .equals()aynı nesneyse var olarak değerlendirilir.

Kullanmanız gereken içerikleri karşılaştırmak istiyorsanız Arrays.equals(a, b)

BTW: Benim tasarladığım yol bu değil. ;)



1

Diziyi genel bir HashMap anahtarı olarak kullanmaya çalışıyorsanız, bu işe yaramayacaktır. Diziyi tutan equals(...)ve hashcode(...)yöntemi java.util.Arrays yöntemlerinden sonuçları döndüren özel bir sarmalayıcı nesnesi oluşturmayı düşünün . Örneğin...

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


}

Bu sarmalayıcı sınıfının nesneleri, sizin için bir anahtar olarak iyi çalışır ve yöntemlerin HashMap<MyByteArray, OtherType>temiz kullanımına izin verir .equals(...)hashCode(...)


0

Değer eşitliği yerine nesne kimliğini test ettiğiniz için yanlış döndürüyorlar. Bu, yanlış döndürür çünkü dizileriniz aslında bellekteki farklı nesnelerdir.

Değer eşitliğini test etmek istiyorsanız, java.util.Arrays içindeki kullanışlı karşılaştırma işlevlerini kullanmalısınız.

Örneğin

import java.util.Arrays;

'''''

Arrays.equals(a,b);

0

Ayrıca kullanabilirsiniz ByteArrayComparatorgelen Apache Directory . Eşittir'e ek olarak , bir dizinin diğerinden daha büyük olup olmadığını karşılaştırmanıza izin verir .


0

Bunun için deneyin:

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

Bundan da emin değilim, ama işe yarayabilir bunu deneyin.


0

neden a [] eşit değildir b []? Çünkü equalsişlev gerçekten çağrıldı Byte[]ya da byte[]öyle Object.equals(Object obj). Bu işlev yalnızca nesne tanımlamasını karşılaştırır, dizinin içeriğini karşılaştırmaz.


0

Guava TreeRangeMap ile karşılaştırılabilir kılan bir dizi sarmalayıcı aradım. Sınıf karşılaştırıcı kabul etmiyor.

Biraz araştırma yaptıktan sonra, JDK'dan ByteBuffer'ın bu özelliğe sahip olduğunu ve orijinal diziyi kopyalamadığını fark ettim. ByteBuffer :: asLongBuffer ile 8 bayt ile daha hızlı karşılaştırabilirsiniz (ayrıca kopyalamaz). Varsayılan olarak ByteBuffer :: wrap (bayt []) BigEndian kullanır, bu nedenle sıra ilişkisi tek tek baytları karşılaştırmakla aynıdır.

.


0

Java bayt karşılaştırması,

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

Çünkü ne dizinin ne ==de equals()yöntemi içerikleri karşılaştırmaz; her ikisi de yalnızca nesne kimliğini değerlendirir ( ==her zaman yapar ve equals()üzerine yazılmaz, bu nedenleObject kullanılmaktadır).

İçeriği karşılaştırmak için kullanın Arrays.equals().



0

Arrays.equalsBir karşılaştırıcı için yeterli değildir, haritanın verileri içerip içermediğini kontrol edemezsiniz. Ben gelen kodu kopyalayıp Arrays.equalsbir inşa etmek değiştirilmiş 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

Bunu yapmanın daha hızlı bir yolu var:

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

2
"Daha hızlı" derken "daha yavaş" demek istiyorsun.
divegeek
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.