如何比较Java Byte[] 数组?

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

我不知道为什么它们都打印出false。

当我运行"java ByteArray"时,答案是"false false false false"。

我认为a[]等于b[],但JVM告诉我我错了,为什么?


1
可能是比较两个字节数组?(Java)的重复问题。 - Vadzim
Arrays.equals可以正常工作。在此处运行并检查 https://onecompiler.com/java/3wc4ec2su - karthikdivi
16个回答

240

如果您想比较包含基本类型值(如字节)的数组的实际内容,请使用Arrays.equals()

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

使用Arrays.deepEquals来比较包含对象的数组。


如果我有一个 'HashMap<byte[], IoBuffer>' 并且我 'put(a, buffer)',如果我 'print(map.containsKey(b))' 它会打印 "false",这是同样的原因吗? - Lazy
3
@Lazy:是的,原因相同……你不能在映射中使用原始的byte[]作为键……在这里阅读更多信息:https://dev59.com/O3NA5IYBdhLWcg3wL6yx - Lukasz

9
因为它们不相等,即它们是具有相等元素的不同数组。 尝试使用Arrays.equals()或Arrays.deepEquals()。

2
这是Java的一部分荒谬之处:为什么要使用来自另一个类的静态方法来比较另一个类中的对象?也就是说:为什么他们没有重写equals()方法? - U. Windl
@U.Windl 这是一种干净的代码设计模式:数据结构应该与逻辑分离。根据我的经验,这种方式使代码更加透明,进一步开发也更容易。 - JHead

6

由于byte[]是可变的,因此仅当它是相同对象时才被视为.equals()

如果要比较内容,您必须使用Arrays.equals(a, b)

顺便说一句:这不是我设计的方式。;)


1

尝试这个:

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

我也不确定,但你可以试试,也许会起作用。


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(...) 方法。


1

你看过Arrays.equals()了吗?

编辑:如果根据你的评论,问题是使用字节数组作为HashMap键,则请参见this question


如果我有一个 'HashMap<byte[], IoBuffer>' 并且我 'put(a, buffer)',如果我 'print(map.containsKey(b))' 它会打印 "false",这是同样的原因吗? - Lazy
@Lazy - 请参考https://dev59.com/O3NA5IYBdhLWcg3wL6yx。 - Dan Vinton

1

因为 == 和数组的equals()方法都不比较内容; 它们只评估对象标识( == 始终如此,而equals()未被覆盖,因此正在使用来自Object的版本)。

要比较内容,请使用{{link1:Arrays.equals()}}。


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

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

0

它们返回 false,因为您正在测试对象身份而不是值相等。这会返回 false,因为您的数组实际上是内存中不同的对象。

如果要测试值相等性,应该使用 java.util.Arrays 中的便捷比较函数

例如:

import java.util.Arrays;

'''''

Arrays.equals(a,b);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接