Java-equals()和toSting()用法(面向对象编程思想)

equals()方法与“==”运算符:
1、equals()方法只能比较引用类型,“==”可以比较引用类型及基本类型。
2、“==”进行比较的时候,引用类型数据比较的是引用,即内存地址,基本数据类型比较的是值。(其实比的就是操作数栈中的内容,即大家平时讲的内存地址)
3、默认的equals()方法比较的是内存地址,基本等同于“==”(从Object的源代码可看出)。但对类File、String、Date及包装类来说,是比较的值而不是内存地址
MyEclipse使用(查看API类的源代码,以Object类的equals方法为例)
这里写图片描述
连按Ctrl+O:第1次是弹出窗口显示当前类的成员变量与成员方法,第2次(第3次)是显示(隐藏)从父类继承的成员信息。
很多我们自己做的类中如果想把属性相等的对象看成相等,也要同样对equals()方法进行覆盖(为确保覆盖,要写成public boolean equals(Object obj)的形式,可从Object类中拷,也可在MyEclipse中自动生成)。
(1)用==检查是否参数就是这个对象的引用
(2)判断要比较的对象是否为null,如果是null,返回false
(3)用instanceof判断参数的类型是否正确
(4)把参数转换成合适的类型
(5)比较对象属性值是不是匹配
另外:如果对象的属性又是一个引用类型的话,要继续调用该引用类型的equals()方法,直到最后得出相同还是不同的结果。
注:覆盖equals应该连带覆盖hashCode方法
哈希值(hashCode)是一个对象的内存地址的散列值,同一个对象的内存地址是相同的,因此它的哈希值也相同。
Java中对hashCode的规定如下:
1)在同一个应用程序执行期间,对同一个对象调用 hashCode(),必须返回相同的整数 结果——前提是equals()所 比较的信息都不曾被改动过。至于同一个应用程序在不同执行期所得的调用结果,无需一致。
2)如果两个对象被equals(Object)方法视为相等,那么对这两个对象调用hashCode()必须获得相同的整数结果。
3)如果两个对象被equals(Object)方法视为不相等,那么对这两个对象调用hashCode()不必产生不同的整数结果。然而程序员应该意识到,对不同对象产生不同的整数结果,有可能提升hashTable(集合框架中的一个类)的效率。
总之,当我们覆盖了equals方法之后,如果不连带覆盖hashCode,那么调用hashCode方法的其它类就不能返回按Java原来设想的那样工作了。如,使用集合对该类对象进行存取操作时就可能会出问题。因为:Set接口及其实现类在集合中有点特殊:它的底层实现方式是MAP;它在存放或读取时都是先按hashCode来查找(本质是判断是否相等),然后再调equals判断相等及做相应操作。因此,如果两个对象的hashCode值不同,则肯定查找不到,因而不可能会执行equals及后续操作。
hashCode是按照一定的算法得到的一个数值,是对象的散列码值。主要用来在集合中实现快速查找等操作,也可以用于对象的比较。

public class Person {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}
public class Employee {
    private String id;
    private String name;
    private int salary;
    public Employee(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getSalary() {
        return salary;
    }
    public void setSalary(int salary) {
        this.salary = salary;
    }
    //把每一个对象的地址映射成一个整数,在对集合或空间的的大小取余得出地址数(如果已存,则存在下一个地址,直到找到存储位置),下次寻找时也是按照这个规律
    //alt+shift+s 再加t,myelipes自动生成,选择判断的两个对象是否相等的的决定属性
    //注:
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Employee other = (Employee) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }
}
public class EqualsDemo {
    public static void main(String[] args) {
        Person p1=new Person("Jack",20);
        Person p2=new Person("Jack",20);
        if(p1==p2){
            System.out.println("yes");
        }else{
            System.out.println("no");
        }
        if(p1.equals(p2)){
            System.out.println("yes2");
        }else{
            System.out.println("no2");
        }
        System.out.println("==================");
        Employee e1=new Employee("1001");
        e1.setName("Jack");
        e1.setSalary(5000);
        Employee e2=new Employee("1001");
        e2.setName("Jack");
        if(e1.equals(e2)){
            System.out.println("yes3");
        }else{
            System.out.println("no3");
        }
        System.out.println("=========2==========");
        System.out.println(e2);
        int n=2;
        System.out.println(n);
    }
}

toString()方法是Object类中定义的另一个重要方法,其格式为:
public String toString(){……}
方法的返回值是String类型,用于描述当前对象的有关信息。Object类中实现的toString()方法是返回当前对象的类型和内存地址信息,但在一些子类(如String, Date等)中进行了重写,也可以根据需要在用户自定义类型中重写toString()方法,以返回更适用的信息。
除显式调用对象的toString()方法外,在进行String 与其它类型数据的连接操作时,会自动调用toString()方法,其中又分为两种情况:
(1)引用类型数据直接调用其toString()方法转换为String 类型;
(2)基本类型数据先转换为对应的包装类型,再调用该包装类的toString()方法转换为String类型。
如何测试(更改)底层API:
1)测试int是否会被自动先转换成Integer然后输出。
这里写图片描述
2)更改底层API中Integer类中的toString方法,在其中加入我们的信息输出,观察是否会被执行。
首先拷贝两份份rt文件(一个备份,一个更改)
这里写图片描述
用360压缩打开src.zip在java中找到lang包,再找Integer.java,复制到当前src文件中
这里写图片描述
3)更改Integer的源代码,用编译后的.class替换JRE中的对应类文件
打开修改添加信息
这里写图片描述
用编译后的.class替换JRE中的对应类文件
这里写图片描述
这里写图片描述
这里写图片描述
运行结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值