【问题标题】:Java: How to test on array equality?Java:如何测试数组相等性?
【发布时间】:2011-12-24 11:08:56
【问题描述】:

为什么下面的代码打印"Different."

boolean[][] a = { {false,true}, {true,false} };
boolean[][] b = { {false,true}, {true,false} };

if (Arrays.equals(a, b) || a == b)
    System.out.println("Equal.");
else
    System.out.println("Different.");

【问题讨论】:

  • 我总是先测试a == b,或者根本不测试。如果equals 为真,则第二个表达式应始终为真。
  • 无论如何,标准实现都是从那个检查开始的,所以我个人会忽略它。
  • 应该只表示两者都给假。
  • @PeterLawrey 实际上,你的意思是如果 == 为真,那么 equals 应该为真。

标签: java arrays equality


【解决方案1】:

为什么下面的代码打印"Different."

因为Arrays.equals 执行比较。由于数组从Object 继承了它们的equals 方法,因此将对内部数组执行身份比较,这将失败,因为ab 不引用相同数组。

如果您更改为Arrays.deepEquals,它将按预期打印"Equal."

【讨论】:

  • 文档对 Array.equals 说:“如果两个指定的 Objects 数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,则这两个数组被认为是相等的,并且所有对应的两个数组中的元素对相等。”所以这不意味着一个完整的比较......?
  • 不,因为ab 的元素不会相互equals(...)。自己试试看:a[0].equals(b[0]) 你会发现它是假的。
  • 在调用deepEquals之前检查a == b会更好,不是吗?
  • 不,最好把多余的部分放在一起。 (Arrays.equals 的标准实现无论如何都是从那个检查开始的。)
  • 请注意,Arrays.equals 对于一维数组来说已经足够了:在这个例子中,Arrays.equals(a[0], b[0]) 为真。
【解决方案2】:

真的不明显。

首先,== 运算符只是比较两个指针。因为ab 是位于不同内存地址的不同对象,所以a == b 将返回false(嘿,Java 纯粹主义者,我知道== 实际上比较对象身份。我只是在说教)。

现在让我们看看equals()实现数组

boolean[] c = new boolean[] { false, true, false };
boolean[] d = new boolean[] { false, true, false };

if (c.equals(d)) {
    System.out.println("Equals");
} else {
    System.out.println("Not equals");
}

这将打印Not equals,因为没有数组实例实际实现equals() 方法。因此,当我们调用<somearray>.equals(<otherarray>) 时,我们实际上是在调用Object.equals() 方法,它只是比较两个指针。

也就是说,请注意您的代码实际上是这样做的:

boolean[] a0 = new boolean[] { false, true };
boolean[] a1 = new boolean[] { true, false };
boolean[] b0 = new boolean[] { false, true };
boolean[] b1 = new boolean[] { true, false };
boolean[][] a = new boolean[][] { a0, a1 };
boolean[][] b = new boolean[][] { b0, b1 };

if (Arrays.equals(a, b) || a == b)
    System.out.println("Equal.");
else
    System.out.println("Different.");

Arrays.equals(a, b) 最终会调用a0.equals(b0),而false 将返回。因此,Arrays.equals(a, b) 也将返回 false

因此您的代码将打印Different.,我们得出结论,Java 相等有时会很棘手。

【讨论】:

    【解决方案3】:

    对多维数组使用 Arrays.deepEquals()。

    【讨论】:

    • 大声笑,这是我一直在寻找的答案
    【解决方案4】:
    public static boolean equal(double[][] a, double[][] b) {
            if (a == null) {
                return (b == null);
            }
            if (b == null) {
                return false;  // already know 'a' isn't null
            }
            if (a.length != b.length) {
                return false;
            }
            for (int i = 0; i < a.length; i++) {
                if (!Arrays.equals(a[i], b[i])) {
                    return false;
                }
            }
            return true;
        }
    

    【讨论】:

    • 重新实现Arrays.deepEquals 不是一个好习惯。到目前为止给出的答案涵盖了很好的解释和解决方案。
    猜你喜欢
    • 2010-10-02
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    • 2014-06-25
    • 2014-11-20
    • 2011-06-11
    相关资源
    最近更新 更多