C# 中的 == 和 equals()有什么区别?/java中==和equals和hashCode的理解

int age = 25;
short newAge = 25;
Console.WriteLine(age == newAge);  //true
Console.WriteLine(newAge.Equals(age));//false
Console.ReadLine();

int和short为原始类型,但与“==”比较返回true,equals()比较返回false。为什么呢?
Answers:
简而言之:
“equals()”相比“= =”复杂。

具体来说:
原始类型覆盖(override)基类的object.Equals(object),并且当括弧中的object与其类型和值相同时返回true (注意Nullable类型也适合上述判断;非空Nullable类型总是装箱到一个基础类型实例)。

由于newAge是short,因此在object是short且值与newAge值相等时,newAge.Equals(object)返回true。你传递的是一个int对象,所以它返回false。

相比之下,“= =”运算符被定义为带两个整形(int)或两个短整型(short)或两个长整形(long)的运算。当“= =”两个参数一个是整形和一个短整型时,编译器会隐式转换short为int,并比较转换后int值大小。
使其工作其他方法:

原始类型也有自己的equals()方法,equals接受相同的类型的参数。

如果你写age.Equals(newAge),编译器将选择int.Equals(int)作为最好的重载(overload)方法且隐式转换short为int。然后,它会返回true,因为这种方法直接比较两个int值大小。

short也有一个short.Equals(short)方法,但是int类型不能隐式转换为short,所以就不会调用它。

你可以使用cast转换强制调用这个方法:
    
Console.Writeline(newAge.Equals((short)age));//true

这将直接调用short.Equals(short),没有装箱操作。如果age大于32767,它会抛出一个溢出异常。

你也可调用short.Equals(object)这个重载,但需要明确地传递一个经过装箱的具有相同类型的对象:

Console.WriteLine(newAge.Equals((object)(short)age));// true

像前面可选方法(short.Equals(short))一样,如果大小超过short范围,同样抛出一个溢出异常。不同于以往的解决方案,它将short装箱成一个object——浪费time和memory。
Source Code:

这里是实际中使用的Equals():

    
public override bool Equals(Objectobj) {
 
       if(!(obj is Int16)) {
 
           return false;
 
       }
 
       return m_value == ((Int16)obj).m_value;
 
   }
 
   public bool Equals(Int16 obj)
 
   {
 
       returnm_value == obj;
 
   }

java ==和equals和hashCode的理解

今天做面试题的时候遇到了一个问题,问题的代码如下:

    import java.util.HashMap;  
    import java.util.Map;  
      
      
    public final class PhoneNumber {  
       private final short areaCode;  
       private final short prefix;  
       private final short lineNumber;  
       public PhoneNumber(int areaCode,int prefix,int lineNumber){  
           rangeCheck(areaCode, 999, "area code");  
           rangeCheck(prefix, 999, "prefix");  
           rangeCheck(lineNumber, 9999, "line number");  
           this.areaCode=(short)areaCode;  
           this.prefix=(short)prefix;  
           this.lineNumber=(short)lineNumber;  
       }  
       private static void rangeCheck(int arg,int max,String name){  
           if(arg<0||arg>max){  
               throw new IllegalArgumentException(name+":"+arg);  
           }  
       }  
      
    @Override  
    public boolean equals(Object o) {  
      if(o==this)  
          return true;  
      if(!(o instanceof PhoneNumber))  
          return false;  
      PhoneNumber pn=(PhoneNumber) o;  
      return (pn.lineNumber==lineNumber)&&(pn.prefix==prefix)&&(pn.areaCode==areaCode);  
        return false;  
      }  
     public static void main(String[] args){  
         Map<PhoneNumber, String> m=new HashMap<PhoneNumber, String>();  
         PhoneNumber pn=new PhoneNumber(707,067, 5309);  
         m.put(new PhoneNumber(707,067, 5309), "jenny");  
         System.out.println(m.get(new PhoneNumber(707,067, 5309)));  
     }  
    }  

       而问题就是看看程序执行完后的输出结果,我当时一看此题有个疑问但是不确定,他没有重写hashCode方法,又想起equals方法与hashCode的方法建议是一起出现的,所以想到此题有陷阱,但是又不知道什么地方有陷阱。把程序敲了一遍发现输出结果为null,猜到肯定与hashCode相关,于是在Map的put方法前加了一个端点,进入了hashmap的源码进行单步调试,我发现源码中在存取key的时候调用了hashcode方法,而默认如果不重写hashcode方法是调用的默认的hashcode,即对象的哈希码,所以不同的对象有不同的哈希码,然后他根据哈希码进行存储。当调用get方法时又根据哈希码进行取值,如果值存在才进行eqals方法的调用,所以即使equals方法返回是true也是没有用的需要重写hashCode让其返回相同的哈希码。我将代码改成如下形式后返回了jenny。

    import java.util.HashMap;  
    import java.util.Map;  
      
      
    public final class PhoneNumber {  
       private final short areaCode;  
       private final short prefix;  
       private final short lineNumber;  
       public PhoneNumber(int areaCode,int prefix,int lineNumber){  
           rangeCheck(areaCode, 999, "area code");  
           rangeCheck(prefix, 999, "prefix");  
           rangeCheck(lineNumber, 9999, "line number");  
           this.areaCode=(short)areaCode;  
           this.prefix=(short)prefix;  
           this.lineNumber=(short)lineNumber;  
       }  
       private static void rangeCheck(int arg,int max,String name){  
           if(arg<0||arg>max){  
               throw new IllegalArgumentException(name+":"+arg);  
           }  
       }  
      
    @Override  
    public boolean equals(Object o) {  
      if(o==this)  
          return true;  
      if(!(o instanceof PhoneNumber))  
          return false;  
      PhoneNumber pn=(PhoneNumber) o;  
      return (pn.lineNumber==lineNumber)&&(pn.prefix==prefix)&&(pn.areaCode==areaCode);  
        return false;  
      }  
    @Override  
    public int hashCode(){  
        return 7*(new Integer(lineNumber).hashCode())+11*(new Integer(prefix)).hashCode()+13*(new Integer(areaCode).hashCode());  
    }  
     public static void main(String[] args){  
         Map<PhoneNumber, String> m=new HashMap<PhoneNumber, String>();  
         PhoneNumber pn=new PhoneNumber(707,067, 5309);  
         m.put(new PhoneNumber(707,067, 5309), "jenny");  
         System.out.println(m.get(new PhoneNumber(707,067, 5309)));  
         System.out.println(pn.getClass());  
     }  
    }  

现在说一下equals方法和==的区别,==默认是比较两个对象的引用是否相等,equsls如果没被重写默认也是按照==进行比较。==一般用来比较两个基本类型是否相等,我们在比较字符串相等的时候也用equals方法,那是因为在String类中已经将equals方法和hashCode方法进行了覆写,比较的是值的大小。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值