A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© liuyj 中级黑马   /  2012-9-25 20:30  /  2205 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

运算符==跟String类方法Equals()的区别?

评分

参与人数 1技术分 +1 收起 理由
宋天琪 + 1

查看全部评分

7 个回复

倒序浏览
没有重写的时候,两个是一样的效果。但equals重写了后,就有区别了。
回复 使用道具 举报
本帖最后由 张青江 于 2012-9-25 21:05 编辑

String类的equals方法和==方法的比较


对于第二对输出 object g = a 和object h = b ,  在内存中两个不同的对象,所以在栈中的内容是不相同的,故不相等。而g.equals(h)用的是sting的equals()方法故相等(多太)。如果将字符串a和b作这样的修改:  string a="aa";
  string b="aa";
  则,g和h的两个比较都是相等的。这是因为系统并没有给字符串b分配内存,只是将"aa"指向了b。所以a和b指向的是同一个字符串(字符串在这种赋值的情况下做了内存的优化)。
  对于p1和p2,也是内存中两个不同的对象,所以在内存中的地址肯定不相同,故p1==p2会返回false,又因为p1和p2又是对不同对象的引用,所以p1.equals(p2)将返回false。
  对于p3和p4,p4=p3,p3将对对象的引用赋给了p4,p3和p4是对同一个对象的引用,所以两个比较都返回true。
  MSDN中就有介绍啊:
  下面的规则概括了 Equals 方法和等号运算符 (==) 的实现准则:
  每次实现 Equals 方法时都实现 GetHashCode 方法。这可以使 Equals 和 GetHashCode 保持同步。
  每次实现相等运算符 (==) 时,都重写 Equals 方法,使它们执行同样的操作。这样,使用 Equals 方法的基础结构代码(如 Hashtable 和 ArrayList)的行为就与用相等运算符编写的用户代码相同。
  每次实现 IComparable 时都要重写 Equals 方法。
  实现 IComparable 时,应考虑实现相等 (==)、不相等 (!=)、小于 ( <) 和大于 (>) 运算符的运算符重载。
  不要在 Equals、GetHashCode 方法或相等运算符 (==) 中引发异常。
  有关 Equals 方法的相关信息,请参见实现 Equals 方法。
  在值类型中实现相等运算符 (==)
  大多数编程语言中都没有用于值类型的默认相等运算符 (==) 实现。因此,只要相等有意义就应该重载相等运算符 (==)。
  应考虑在值类型中实现 Equals 方法,这是因为 System..::.ValueType 的默认实现和自定义实现都不会执行。
  每次重写 Equals 方法时都实现相等运算符 (==)。
  在引用类型中实现相等运算符 (==)
  大多数语言确实为引用类型提供默认的相等运算符 (==) 实现。因此,在引用类型中实现相等运算符 (==) 时应小心。大多数引用类型(即使是实现 Equals 方法的引用类型)都不应重写相等运算符 (==)。
  如果类型是 Point、String、BigNumber 等基类型,则应重写相等运算符 (==)。每当考虑重载加法 (+) 和减法 (-) 运算符时,也应该考虑重载相等运算符 (==)。
  好了,下面是考题,相信答案大家都知道了。

Console.WriteLine((2 + 2) == 4);
object s = 1;
object t = 1;
Console.WriteLine(s == t);
string a = "hello";
string b = String.Copy(a);
string c = "hello";
Console.WriteLine(a == b);
Console.WriteLine((object)a == (object)b);
Console.WriteLine((object)a == (object)c);

  答案:TRUE, FALSE, TRUE, FALSE, TRUE

评分

参与人数 1技术分 +2 收起 理由
宋天琪 + 2

查看全部评分

回复 使用道具 举报
通俗点讲就是==比较的永远是值是否相等,不分引用类型还是值类型
而Equals()方法对于值类型比较的是值是否相等而对于引用类型比较的是引用是否相等

评分

参与人数 1技术分 +1 收起 理由
宋天琪 + 1

查看全部评分

回复 使用道具 举报
==比较的是引用,Equals()比较的是值
string a = new string(new char[] { 'a', 'b', 'c' });
            string b = new string(new char[] { 'a', 'b', 'c' });
            object f = a;
            object h = b;
            bool z = (f == h);
            bool e = f.Equals(h);
            Console.WriteLine("f的值是{0},h的值是{1};\n用==比较结果:{2},用Equals比较结果:{3}", f, h,z,e);
            Console.Read();

评分

参与人数 1技术分 +1 收起 理由
郑文 + 1

查看全部评分

回复 使用道具 举报
==和equals的区别,在字符串比较的情况下,前者是比较两个字符串变量所指向的内存地址是否相同,而后者是比较两个字符串变量的值是否相同 只有在整型比较的时候,==和equals才是相等的。

评分

参与人数 1技术分 +1 收起 理由
郑文 + 1

查看全部评分

回复 使用道具 举报
在.NET中,ReferenceEquals()方法是专门用来表示引用相等的;

==运算符和Equals()方法都可以用来表示引用相等和值相等。对于值类型而言, ==和Equals()方法是一样的,使用上没有什么区别。那么重点是引用类型:

从效果上说,对于引用类型, ==运算符表示引用相等(string有运算符重载,除外),而Equals()表示值相等。从效果上讲,这个说法好像不算错,网上也有这么一种说法。



从原理上说,无论是对值类型还是对于引用类型,==运算符和Equals()方法是相同的,当然排除了一个是运算符一个是方法的这个区别。为什么这样说呢?对于值类型而言,==运算符表示值相等,而Equals()方法在绝大多数的值类型中都重写了这个方法,使之能够支持值类型。在值类型这个层面的区别基本可以忽略。而对于引用类型而言, ==运算符表示引用相等(string除外),Equals()默认只支持引用类型(见第二个代码块),也表示引用相等。因此有==运算符既支持引用相等,也支持值相等,同样Equals()方法也支持值相等和引用相等, 所以==运算符和Equals()方法是相同的。那么为什么第三个代码块中的==运算符和Equals()方法的结果屡有不同呢?答案是多肽:子类实例指向父类引用,同种语义不同行为。虽然object为引用类型,而引用类型的Equals()方法的结果应该是引用相等,但由于多肽的存在,object类型的变量中实际存放的是值类型,所以调用的Equals()方法是子类实例的,因此才体现不相等的结果。也正因为如此,值相等还是引用相等和多肽这两个不相干的问题,硬是被说成了==运算符是引用相等而Equals()方法是值相等。



个人认为:==运算符和Equals()方法除了运算符和方法的区别外,再没有别的区别。而所谓的Equals()方法表示值相等的说法只是由于多肽而造成的假象。当然,Equals()用于值相等的说法效果上好像也说得过去。

评分

参与人数 1技术分 +1 收起 理由
宋天琪 + 1

查看全部评分

回复 使用道具 举报
==若用于比较字母中不能区分大小写,而Equa()就可以区分,且一个是运算符,一个是方法l

评分

参与人数 1技术分 +1 收起 理由
宋天琪 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马