之前我们比较基本数据类型的方式很简单,1==1,true == true ,2 == 3,通过“==”的方式比较两个数据是否相等。
但是之前,我们使用包装类包装了两个数据,比较这两个包装类的时候,我们发现,即便包装的数据一样,但是使用“==”返回false。
class EqualsTest{ publicstatic void main(String[] args){ Personp1 = new Person("小明","帝都",28); Personp2 = new Person("大明","魔都",22); System.out.PRintln(p1== p2);//false Personp3 = new Person("大明","魔都",22); System.out.println(p3== p2);//false Integerinteger1 = new Integer(1); Integerinteger2 = new Integer(1); System.out.println(integer2== integer1);//false }} class Person{ publicPerson(String name ,String address ,int age){ this.name= name; this.address= address; this.age= age; } Stringname ; Stringaddress; int age;}我们在比较基本数据类型时,可以直接使用==来判断是否相等。
但是,引用数据类型,不可以使用==来判断,即便,两个引用类型指向的对象属性完全一致,但是依然返回false。
这是因为:对象使用“==”比较的话,比较的是引用所指向对象的地址值,比较是对象是否同一个。如下案例,当两个引用变量指向同一个对象,再比较的话,就是true,因为两个变量的引用都是指向同一个对象,所以比较的地址值也一样,所以返回true。否则,返回false.
class EqualsTest{ publicstatic void main(String[] args){ Personp1 = new Person("小明","帝都",28); Personp2 = p1; System.out.println(p1== p2);//true }} class Person{ publicPerson(String name ,String address ,int age){ this.name= name; this.address= address; this.age= age; } Stringname ; Stringaddress; int age;}但是,在开发中,我们经常会遇到一种问题,就是我们需要把属性相同的两个对象认为是同一个对象。这个时候,我们使用equals方法来解决这种问题。
比较两个对象,Object类提供了equals方法供我们自定义比较两个对象是否相等。在定义类的时候,我们可以重写该方法,来达到自定义判断两个对象是否相等的目的。当对象调用equals方法的时候,就会执行该对象重写的equals方法来判断与传入的对象是否是同一个对象,这样就达到了手动控制的目的。
但是,如果没有重写equals方法,那么就是执行默认的object提供的equals方法。
我们翻开原码发现,默认的提供的equals方法,其实就是使用==来比较两个对象,比较的是指向的对象的地址值。当我们没有重写equals方法,执行该方法实际就是执行了==运算,比较两个对象的地址值是否同一个。
一般来说,java提供的很多类都重写了equals方法,用来判断。
练习:
class EqualsTest{ public static void main(String[] args){ Person p1 = new Person("小明","帝都",28); Person p2 = new Person("大明","魔都",22); System.out.println(p1.equals(p2));//false Person p3 = new Person("大明","魔都",22); System.out.println(p3.equals(p2));//true }} class Person{ public Person(String name ,String address ,int age){ this.name= name; this.address= address; this.age= age; } public boolean equals(Object obj) { //判断地址是否一样 if(this== obj){ retur ntrue; } //判断传入的对象引用是否为null if(obj== null){ return false; } //判断传入的对象是否该属于本类类型对象 if(!(obj instanceof Person)){ return false; } //将传入对象强转 Person ap = (Person)obj; //依次判断传入对象的属性与本对象属性是否一致 //判断name if(this.name== null){ if(ap.name!=null){ return false; } }else{ if(!this.name.equals(ap.name)){ return false; } } //判断age if(this.age!= ap.age){ return false; } //判断address if(this.address== null){ if(ap.address!=null){ return false; } }else{ if(!this.name.equals(ap.name)){ return false; } } //到这一步,说明所有属性都相同 return true; } String name ; String address; int age;}toString方法:(自定义打印对象内容)
有的时候,我们需要知道一下对象的内容,那么我们将对象打印输出查看,但是我们直接输出的话,打印结果如下:
我们发现,这个结果并不是我们需要的。假设我们需要打印对象,打印对象的内容如属性,那么这个时候,我们需要自定义一下打印的内容。
Object类提供了默认方法toString方法,该方法返回该对象的字符串表示形式。他默认打印的是对象的类型+@+哈希值。当我们需要自定义对象的字符串表现形式时,我们可以重写toString方法。
如下:object类中源码默认打印:
public String toString() { return getClass().getName() + "@" +Integer.toHexString(hashCode()); }我们发现,直接打印对象,就会默认调用该对象的toString方法,打印该方法的返回值。
class EqualsTest{ public static void main(String[] args){ Person p1 = new Person("小明","帝都",28); //直接打印对象,就是打印对象toString方法返回值 System.out.println(p1); Person p2 = new Person("大明","帝都",22); System.out.println(p2.toString()); }} class Person{ public Person(String name ,String address ,int age){ this.name= name; this.address= address; this.age= age; } public String toString(){ Stringresult = "name:" + name +";address:" + address+";age:" + age; return result; } public boolean equals(Object obj) { //判断地址是否一样 if(this== obj){ return true; } //判断传入的对象引用是否为null if(obj== null){ return false; } //判断传入的对象是否该属于本类类型对象 if(!(obj instanceof Person)){ return false; } //将传入对象强转 Person ap = (Person)obj; //依次判断传入对象的属性与本对象属性是否一致 //判断name if(this.name== null){ if(ap.name!=null){ return false; } }else{ if(!this.name.equals(ap.name)){ return false; } } //判断age if(this.age!= ap.age){ return false; } //判断address if(this.address== null){ if(ap.address!=null){ return false; } }else{ if(!this.name.equals(ap.name)){ return false; } } //到这一步,说明所有属性都相同 return true; } String name ; String address; int age;}
哈希值:
在之前,我们翻开Object的源码发现,会打印类名+@+哈希值。
那么哈希值到底是什么东西?
每个对象,都会有一个唯一的哈希值,当使用“==”比较两个对象,其实比较的就是哈希值!
哈希值是当创建对象后,由虚拟机自动生成,无法更改。
当然,每个对象也提供了获取哈希值的方法hashCode方法,默认返回的就是哈希值。
该方法是Object提供的,可以重写该方法。
什么时候需要用到重写该方法?
在之后课程集合中,判断一些对象是否重复,用到哈希值,重写hashCode方法。
新闻热点
疑难解答