首页 > 学院 > 开发设计 > 正文

处理对象

2019-11-08 01:55:39
字体:
来源:转载
供稿:网友

==和equals

之前我们比较基本数据类型的方式很简单,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方法。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表