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 <byte []、IoBuffer>'とi 'put(a、buffer)'がある場合、, 'print(map.containsKey(b))'の場合、「false」と出力されますが、同じですか理由????
レイジー

3
@Lazyは:はい、理由は同じです...あなたがマップにキーとして生のバイト[]を使用することはできません...もっとここで読む:stackoverflow.com/questions/1058149/...
ルカシュ

6

つまり、それらは等しくありません。つまり、内部に同じ要素を持つ異なる配列です。

Arrays.equals()またはを使用してみてくださいArrays.deepEquals()


これはJavaのナンセンスの一部です。なぜ別のクラスの静的メソッドを使用して、別のクラスのオブジェクトを比較するのでしょうか。つまり、なぜequals()メソッドをオーバーライドしなかったのですか?
U. Windl

3

byte []は変更可能である.equals()ため、同じオブジェクトである場合にのみ存在するものとして扱われます。

あなたが使用しなければならない内容を比較したい場合 Arrays.equals(a, b)

ところで:それは私がそれを設計する方法ではありません。;)


1

見ましたか Arrays.equals()か?

編集:コメントに従って、問題がHashMapキーとしてバイト配列を使用している場合は、この質問を参照してください。


'HashMap <byte []、IoBuffer>'とi 'put(a、buffer)'がある場合、, 'print(map.containsKey(b))'の場合、「false」と出力されますが、同じですか理由????
レイジー


1

配列を一般的なHashMapキーとして使用しようとしている場合、それは機能しません。配列を保持するカスタムラッパーオブジェクトを作成し、そのequals(...)and 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

これを試してください:

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

これについてもわかりませんが、うまくいくかどうか試してみてください。


0

なぜa []はb []と等しくないのですか?そのためequalsの機能が実際に呼ばれるByte[]byte[]ですObject.equals(Object obj)。この関数は、オブジェクトの識別のみを比較し、配列の内容は比較しません。


0

グアバTreeRangeMapでの使用に匹敵する配列ラッパーを探しました。クラスはコンパレータを受け入れません。

調査の結果、JDKのByteBufferにこの機能があり、元の配列がコピーされないことがわかりました。さらに、ByteBuffer :: asLongBufferを一度に8バイト高速に比較できます(コピーも行われません)。デフォルトでは、ByteBuffer :: wrap(byte [])は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()メソッドも配列のメソッドも内容を比較しないためです。どちらもオブジェクトIDのみを評価します(==常に実行され、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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.