java中的比较:instanceof、equals(hashcode)、==

先看看我的一段测试程序

import javassist.expr.Instanceof; class Person{ String s; Person(String s){ this.s=s; } } class Man extends Person{ Man(String s) { super(s); // TODO Auto-generated constructor stub } } public class Itest { public static void main(String[] args) { int i=9; int j=9; String s1="123"; String s2="123"; String s3=new String("123"); String s4=new String ("123"); Person p1=new Person("123"); Person p2=new Person("123"); Person p3=p1; Man m=new Man("123"); System.out.println("basic type compare"); System.out.println(i==j); System.out.println("String type compare"); System.out.println(s1==s2); System.out.println(s1.equals(s2)); System.out.println(s1==s3); System.out.println(s1.equals(s3)); System.out.println(s3.equals(s4)); System.out.println("Object type compare"); System.out.println(p1==p3); System.out.println(p1.equals(p3)); System.out.println(p1.equals(p2)+":p1 compare to p2"); System.out.println((p1.hashCode()==p2.hashCode())+":p1.hashcode compare to p2.hashcode"); System.out.println((p1==p2)+":p1==p2"); System.out.println("instanceof"); System.out.println(m instanceof Man ); //System.out.println(Man instanceof Person); } }  

控制台输出结果:

basic type compare true String type compare true true false true true Object type compare true true false:p1 compare to p2 false:p1.hashcode compare to p2.hashcode false:p1==p2 instanceof true  

 

1、instanceof:用法:

 

int  boolean  是值数据类型     

   而instanceof  只能 用于 对象 类型

  例如 

正确:

 Integer i; 

      if(i instanceof Integer) 

         System.out.println("i 是 Integer类型");

错误:

  int i;

    if(i instanceof int)

       System.out.println("i 是 int类型"); 

2.首先equals()和hashcode()这两个方法都是从object类中继承过来的。 

 

equals()方法在object类中定义如下: 

 

public boolean equals(Object obj) { 

 

return (this == obj); 

 

 

很明显是对两个对象的地址值进行的比较(即比较引用是否相同)。但是我们必需清楚,当String 、Math、还有Integer、Double。。。。等这些封装类在使用equals()方法时,已经覆盖了object类的equals()方法。是进行的内容比较,而已经不再是地址的比较。依次类推Double、Integer、Math。。。。等等这些类都是重写了equals()方法的,从而进行的是内容的比较。当然了基本类型是进行值的比较,这个没有什么好说的。 

 

我们还应该注意,Java语言对equals()的要求如下,这些要求是必须遵循的: 

 

• 对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。 

 

• 反射性:x.equals(x)必须返回是“true”。 

 

• 类推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。 

 

• 还有一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。 

 

• 任何情况下,x.equals(null),永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”。 

 

以上这五点是重写equals()方法时,必须遵守的准则,如果违反会出现意想不到的结果,请大家一定要遵守。

3、其次是hashcode() 方法,在object类中定义如下: 

 

public native int hashCode(); 

 

说明是一个本地方法,它的实现是根据本地机器相关的。当然我们可以在自己写的类中覆盖hashcode()方法,比如String、Integer、Double。。。。等等这些类都是覆盖了hashcode()方法的。 

 

想要明白hashCode的作用,你必须要先知道Java中的集合。总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set。前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重复。那么这里就有一个比较严重的问题了:要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢?这就是Object.equals方法了。但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。也就是说,如果集合中现在已经有1000个元素,那么第1001个元素加入集合时,它就要调用1000次equals方法。这显然会大大降低效率。于是,Java采用了哈希表的原理。hashCode方法实际上返回的就是对象存储的物理地址(实际可能并不是)。这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了。所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。  

4、当对上面Person类对象进行equals比较时,结果为false。因为没有override Object类中的equals和hashcode方法,比较的仍是对象的地址。此时创建类要重写hashcode和equals方法,自定义合适为true。

你可能感兴趣的:(java,SE)