黑马程序员技术交流社区

标题: 比较数组是否相同为什么这样写会错啊 [打印本页]

作者: 待解封的小刀    时间: 2014-7-16 21:20
标题: 比较数组是否相同为什么这样写会错啊
class Demo
{       
        private int[] arr;
        Demo(int[] arr)//把数组 作为类的成员。通过比较对象是否相同,来确定这个类中的数组是否相同
        {
                this.arr=arr;
       
        }
       
        public boolean equals(Object obj)//对object类进行复写。
        {                                
               
                Demo d=(Demo)obj;
                return this.arr==d.arr;
       
        }

       
}
class ArrEquals
{
        public static void main(String[] args)
        {        int arr1[]={1,2,3};
                int arr2[]={1,2,3};
               
                 Demo p1=new Demo(arr1);
                 Demo p2=new Demo(arr2);
               
               
                System.out.println(p1.equals(p2));
       
       
        }

                           为什么结果是false啊  应该是true才对啊  不知道哪错了 求大神指点啊
}

作者: fantacyleo    时间: 2014-7-16 21:26
你覆写的equals方法,比较的还是数组地址是否相同,而不是数组元素是否相等。Java中,数组,哪怕是元素为基本类型的数组,也是对象。记得:int[] a = new a[3]; 这种写法么?这就体现了数组的本质:用new运算符创建出来的必然是引用类型。你用大括号初始化,不过是语法上的一种简写,本质依然是new。因此,数组变量a是引用类型变量。你在equals里直接用==比较引用类型,依然是地址比较,当然是false
作者: 待解封的小刀    时间: 2014-7-16 22:19
fantacyleo 发表于 2014-7-16 21:26
你覆写的equals方法,比较的还是数组地址是否相同,而不是数组元素是否相等。Java中,数组,哪怕是元素为基 ...

也就是不能把数组看成对象中的成员。 数组只能看作是对象。
作者: fantacyleo    时间: 2014-7-16 22:25
待解封的小刀 发表于 2014-7-16 22:19
也就是不能把数组看成对象中的成员。 数组只能看作是对象。

这两者没有关联。你的代码中,数组当然是对象成员,但它本身也是对象,arr是引用类型变量。如果你在类中定义一个int,也是对象成员,可是int不是引用类型,所以拿==比较没有问题,符合你的要求。但是拿==去比较引用类型,就成了比较地址
作者: 待解封的小刀    时间: 2014-7-16 22:38
fantacyleo 发表于 2014-7-16 22:25
这两者没有关联。你的代码中,数组当然是对象成员,但它本身也是对象,arr是引用类型变量。如果你在类中 ...

那怎么做  我的思想没错啊 这个用equals 怎么比较呢? 是不是equals只能比较基本类型?比较引用的就变成地址了吗?
作者: fantacyleo    时间: 2014-7-16 22:49
待解封的小刀 发表于 2014-7-16 22:38
那怎么做  我的思想没错啊 这个用equals 怎么比较呢? 是不是equals只能比较基本类型?比较引用的就变成 ...

1. for循环下标,逐个元素比较是否相等。
2. 用Arrays工具类中的equals方法比较数组对应元素是否相等。
作者: icris    时间: 2014-7-16 22:51
查到一个数组比较方法
return Arrays.equals(this.arr, d.arr);


作者: 待解封的小刀    时间: 2014-7-16 23:05
icris 发表于 2014-7-16 22:51
查到一个数组比较方法
return Arrays.equals(this.arr, d.arr);

我有一点不明白 这equals 本来是比较对象是否相同的 也就是地址;但是我已经覆盖了这个功能啊 怎么变不了比较内容呢?
像我比较人的年龄是否相同就可以啊。
class Person

      private int age;
      Person(int age)
     {   
          this.age=age;
      }
     public boolean equals(object obj)
      {  Person d=(Person)obj;
         return this.age==d.age;
      }
class PersonDemo
{     
      public static void main(String[] args)
     {   
       Person.d1=new Person(7);
       Person.d2=new Person(7);
      System.out.println(d1.equals(d2));
      }
}  这比较的是年龄啊 有点晕了 。。。。。这个比较的不是地址值啊。




作者: icris    时间: 2014-7-16 23:23
待解封的小刀 发表于 2014-7-16 23:05
我有一点不明白 这equals 本来是比较对象是否相同的 也就是地址;但是我已经覆盖了这个功能啊 怎么变不了 ...

你重写了自己的 Demo 里的 equals ,但是返回值是两个数组的 == 运算,数组比较相等是不能用 == 的,而且数组也没有重写 equals ,用 this.arr.equals(d.arr) 效果和 == 一样,都不能得到正确结果,把 equals 的返回值改成
return Arrays.equals(this.arr, d.arr);
应该就行了。
就是说,你重写了 Demo 的 equals 只能保证返回的不是两个 Demo 对象地址比较,但是返回了两个数组的地址比较,仍然不是正确的结果

作者: 待解封的小刀    时间: 2014-7-17 07:56
icris 发表于 2014-7-16 23:23
你重写了自己的 Demo 里的 equals ,但是返回值是两个数组的 == 运算,数组比较相等是不能用 == 的,而且 ...

哦  我明白了 也就是return this.arr==b.arr 返回的还是地址值的比较是否正确。
大神 我把return改成arrays的形式 还是不行  因为我的Demo中没Arrays啊  怎么在前面加上。
作者: icris    时间: 2014-7-17 08:10
待解封的小刀 发表于 2014-7-17 07:56
哦  我明白了 也就是return this.arr==b.arr 返回的还是地址值的比较是否正确。
大神 我把return改成arra ...
  1.         public boolean equals(Object obj){                                
  2.                 Demo d=(Demo)obj;
  3.                 return Arrays.equals(this.arr, d.arr);
  4.         }
复制代码

Arrays.equals 是静态方法可以直接用,A 大写,我试了一下结果是 true

作者: 亦金亦水    时间: 2014-7-17 08:38
同楼上!!!!!
作者: 待解封的小刀    时间: 2014-7-17 08:44
icris 发表于 2014-7-17 08:10
Arrays.equals 是静态方法可以直接用,A 大写,我试了一下结果是 true

class Demo
{       
        private int[] arr;
        Demo(int[] arr)
        {
                this.arr=arr;
       
        }
       
        public boolean equals(Object obj)
        {                              
               
                Demo d=(Demo)obj;
                return Arrays.equals(this.arr,d.arr);
       
        }

       
}
class ArrEquals
{
        public static void main(String[] args)
        {        int arr1[]={1,2,3};
                int arr2[]={1,2,3};
               
                 Demo p1=new Demo(arr1);
                 Demo p2=new Demo(arr2);
               
               
                System.out.println(p1.equals(p2));
       
       
        }


}

作者: 待解封的小刀    时间: 2014-7-17 08:45
icris 发表于 2014-7-17 08:10
Arrays.equals 是静态方法可以直接用,A 大写,我试了一下结果是 true

class Demo
{       
        private int[] arr;
        Demo(int[] arr)
        {
                this.arr=arr;
       
        }
       
        public boolean equals(Object obj)
        {                              
               
                Demo d=(Demo)obj;
                return Arrays.equals(this.arr,d.arr);
       
        }

       
}
class ArrEquals
{
        public static void main(String[] args)
        {        int arr1[]={1,2,3};
                int arr2[]={1,2,3};
               
                 Demo p1=new Demo(arr1);
                 Demo p2=new Demo(arr2);
               
               
                System.out.println(p1.equals(p2));
       
       
        }

      我这样写的  但是显示Arrays在类中找不到
}

作者: icris    时间: 2014-7-17 08:58
待解封的小刀 发表于 2014-7-17 08:45
class Demo
{       
        private int[] arr;
  1.     /**
  2.      * Returns <tt>true</tt> if the two specified arrays of ints are
  3.      * <i>equal</i> to one another.  Two arrays are considered equal if both
  4.      * arrays contain the same number of elements, and all corresponding pairs
  5.      * of elements in the two arrays are equal.  In other words, two arrays
  6.      * are equal if they contain the same elements in the same order.  Also,
  7.      * two array references are considered equal if both are <tt>null</tt>.<p>
  8.      *
  9.      * @param a one array to be tested for equality
  10.      * @param a2 the other array to be tested for equality
  11.      * @return <tt>true</tt> if the two arrays are equal
  12.      */
  13.     public static boolean equals(int[] a, int[] a2) {
  14.         if (a==a2)
  15.             return true;
  16.         if (a==null || a2==null)
  17.             return false;

  18.         int length = a.length;
  19.         if (a2.length != length)
  20.             return false;

  21.         for (int i=0; i<length; i++)
  22.             if (a[i] != a2[i])
  23.                 return false;

  24.         return true;
  25.     }
复制代码

从源码复制的,真的不能用就复制一下吧…

作者: icris    时间: 2014-7-17 09:02
待解封的小刀 发表于 2014-7-17 08:45
class Demo
{       
        private int[] arr;

想起来了,在最上面加上

import java.util.Arrays;

作者: 待解封的小刀    时间: 2014-7-17 09:18
icris 发表于 2014-7-17 09:02
想起来了,在最上面加上

import java.util.Arrays;

这个是什么意思  有什么作用啊 ?
作者: 待解封的小刀    时间: 2014-7-17 09:20
icris 发表于 2014-7-17 08:58
从源码复制的,真的不能用就复制一下吧…

这个比较 不错
作者: 人心如水    时间: 2014-7-17 09:22
比较的是两个对象,两地址值。年纪是具体指,比较的是值
作者: 待解封的小刀    时间: 2014-7-17 09:50
人心如水 发表于 2014-7-17 09:22
比较的是两个对象,两地址值。年纪是具体指,比较的是值

什么情况 可否解释清楚?年龄这里  我把equals复写了 所以比较的是age的值  不是地址值了啊
作者: 待解封的小刀    时间: 2014-7-17 09:53
icris 发表于 2014-7-17 08:58
从源码复制的,真的不能用就复制一下吧…

我把你的方法  运行了一遍  为什么没结果呢?
我简写了下 没结果 但是编译没出错

class Equals
{
        public  boolean equals(int[] a, int[] a2)
        {
               
                int length = a.length;
        if (a2.length != length)
            return false;

        for (int i=0; i<length; i++)
                {
                         if (a==a2)
                return true;
       
                }
        
        return false;
    }

}
class EqualsArr
{
        public static void main(String[] args)
        {
                int []a={1,2,3,4};
                int []b={1,2,3,4};
                Equals sss=new Equals();
                sss.equals(a,b);
       
       
        }

}
是不是我的主函数写错了啊?
作者: 待解封的小刀    时间: 2014-7-17 10:05
待解封的小刀 发表于 2014-7-17 09:53
我把你的方法  运行了一遍  为什么没结果呢?
我简写了下 没结果 但是编译没出错

这个 明白了 我写错了 谢谢了兄弟。
作者: 待解封的小刀    时间: 2014-7-17 11:21
fantacyleo 发表于 2014-7-16 22:25
这两者没有关联。你的代码中,数组当然是对象成员,但它本身也是对象,arr是引用类型变量。如果你在类中 ...

也就是 ==  这个比较符   在int 型 这些基本的数据类型中 比较的是内容 而== 在引用数据类型 比较的就是他们的地址了   所以对于数组 要用equals 而不是用==  是这样理解的吧  求大神回复。
作者: icris    时间: 2014-7-17 11:27
待解封的小刀 发表于 2014-7-17 11:21
也就是 ==  这个比较符   在int 型 这些基本的数据类型中 比较的是内容 而== 在引用数据类型 比较的就是 ...

数组也不能用 equals …
把 return 换成 return Arrays.equals(arr, d.arr); 在最上面(第一个 class 上面)写上 import java.util.Arrays;
这样就行了。用 eclipse 的时候 import 是自动添加的

作者: F@C    时间: 2014-7-18 11:33
进来学习




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2