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方法进行了覆写,比较的是值的大小。
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方法进行了覆写,比较的是值的大小。