📜  预测以下Java程序的输出

📅  最后修改于: 2020-03-28 11:21:32             🧑  作者: Mango

预测以下Java程序的输出。

class Test
{
    public static void main (String[] args)
    {
        int arr1[] = {1, 2, 3};
        int arr2[] = {1, 2, 3};
        if (arr1 == arr2) // 同arr1.equals(arr2)
            System.out.println("相同");
        else
            System.out.println("不同");
    }
}

输出:

不同

在Java中,数组是一类对象。在上面的程序中,arr1和arr2是对两个不同对象的两个引用。所以,当我们比较ARR1和ARR2,两个参考变量进行比较,因此我们得到的输出为“不同”(见为更多的例子)。

如何比较数组内容?
一种简单的方法是运行循环并逐一比较元素。Java提供了直接方法Arrays.equals()来比较两个数组。实际上,在Arrays类中有一组equals()方法用于不同的原始数据类型(int,char,.. etc),在Objects类型中有一种equals()方法(这是Java中所有类的基础)。

//  到导入java.util.Arrays来使用Arrays.equals().
import java.util.Arrays;
class Test
{
    public static void main (String[] args)
    {
        int arr1[] = {1, 2, 3};
        int arr2[] = {1, 2, 3};
        if (Arrays.equals(arr1, arr2))
            System.out.println("相同");
        else
            System.out.println("不同");
    }
}

输出:

相同

如何深度比较数组内容?
如上所示,Arrays.equals()可以正常工作并比较数组内容。现在的问题是,如果数组内部包含数组或其他引用不同对象但具有相同值的引用,该怎么办?例如,请参见以下程序。

import java.util.Arrays;
class Test
{
    public static void main (String[] args)
    {
        // inarr1和inarr2值相同
        int inarr1[] = {1, 2, 3};
        int inarr2[] = {1, 2, 3};
        Object[] arr1 = {inarr1};  // arr1 只有一个元素
        Object[] arr2 = {inarr2};  // arr2 也只有一个元素
        if (Arrays.equals(arr1, arr2))
            System.out.println("相同");
        else
            System.out.println("不同");
    }
}

输出:

不同

因此Arrays.equals()无法进行深度比较。Java为此Arrays.deepEquals()提供了另一种方法,该方法可以进行深度比较。

import java.util.Arrays;
class Test
{
    public static void main (String[] args)
    {
        int inarr1[] = {1, 2, 3};
        int inarr2[] = {1, 2, 3};
        Object[] arr1 = {inarr1};  // arr1 只有一个元素
        Object[] arr2 = {inarr2};  // arr2 也只有一个元素
        if (Arrays.deepEquals(arr1, arr2))
            System.out.println("相同");
        else
            System.out.println("不相同");
    }
}

输出:

相同

Arrays.deepEquals()如何工作?
它使用具有的任何自定义equals()方法比较两个对象(如果它们具有除Object.equals()之外实现的equals()方法)。如果不是,则此方法将继续递归地逐个字段比较对象。遇到每个字段时,它将尝试使用派生的equals()(如果存在),否则它将继续递归。
此方法适用于循环对象图,如下所示:A-> B-> C-> A。它具有循环检测功能,因此可以比较任何两个对象,并且永远不会进入无限循环(来源:https : //code.google.com/p/deep-equals/)。
练习:预测以下程序的输出

import java.util.Arrays;
class Test
{
   public static void main (String[] args)
   {
      int inarr1[] = {1, 2, 3};
      int inarr2[] = {1, 2, 3};
      Object[] arr1 = {inarr1};  // arr1 只有一个元素
      Object[] arr2 = {inarr2};  // arr2 也只有一个元素
      Object[] outarr1 = {arr1}; // outarr1 只有一个元素
      Object[] outarr2 = {arr2}; // outarr2 只有一个元素
      if (Arrays.deepEquals(outarr1, outarr2))
          System.out.println("相同");
      else
          System.out.println("不同");
    }
}