equals方法使用小结

先来简单小结一下equals的用法: 

1.首先如果只是基本数据类型,那么判断两个变量是否相等用  == 即可

2.比较对象,有两种情况:

        一种就是使用java已经给我们提供好的类。如包装器类型,如Boolean、Double、Integer,这些只要直接使用equals比较即可,因为他们内部已经重写了equals和hashCode方法,所以我们可以直接使用。

        二种当然也是比较经常使用的自定义类型。如果要比较自定义的的两个类的对象是否相等,就需要我们重写equals和hashCode方法。如下:

 @Override
    public boolean equals(Object otherObject) {
        if (this == otherObject) {
            return true;
        }
        if (otherObject == null) {
            return false;
        }
        if (getClass() != otherObject.getClass()) {
            return false;
        }

        Employee other = (Employee)otherObject;
        boolean flag = name.equals(other.getName()) && salary.equals(other.getSalary()) && hireDay.equals(other.getHireDay());
        return flag;
    }

    @Override
    public int hashCode() {
        return name.hashCode() + hireDay.hashCode() + salary.hashCode();
    }

这两者是对应的,必须都要重写。

 

==================================代码示例======================

 

本代码摘抄至‘Java核心技术’,因为版本的问题,修改的些许代码。以下直接贴出代码。。

 

1.雇员类:

package com.lin.model;

import java.time.LocalDate;

/**
 * 雇员类
 *
 * @author linrui
 * @date 2019/03/27
 * */
public class Employee {

    private String name;
    private Double salary;
    private LocalDate hireDay;

    public Employee(String name, Double salary, int year, int month, int day) {
        this.name = name;
        this.salary = salary;
        this.hireDay = LocalDate.of(year, month, day);
    }

    public String getName() {
        return name;
    }

    public Double getSalary() {
        return salary;
    }


    public LocalDate getHireDay() {
        return hireDay;
    }

    public void raiseSalary(Double byPercent) {
        double raise = salary * byPercent/100;
        salary += raise;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", salary=" + salary +
                ", hireDay=" + hireDay +
                '}';
    }

    @Override
    public boolean equals(Object otherObject) {
        if (this == otherObject) {
            return true;
        }
        if (otherObject == null) {
            return false;
        }
        if (getClass() != otherObject.getClass()) {
            return false;
        }

        Employee other = (Employee)otherObject;
        boolean flag = name.equals(other.getName()) && salary.equals(other.getSalary()) && hireDay.equals(other.getHireDay());
        return flag;
    }

    @Override
    public int hashCode() {
        return name.hashCode() + hireDay.hashCode() + salary.hashCode();
    }
}

2.经理类(雇员类的子类)

package com.lin.model;

import java.time.LocalDate;

/**
 * 经理类
 *
 * @author linrui
 * @date 2019/03/27
 * */
public class Manager extends Employee{

    private Double bonus;

    public Manager(String name, Double salary, int year, int month, int day) {
        super(name, salary, year, month, day);
        this.bonus = new Double(0);
    }

    @Override
    public Double getSalary() {
        Double baseSalary = super.getSalary();
        return baseSalary + bonus;
    }
    public void setBonus(Double bonus) {
        this.bonus = bonus;
    }

    @Override
    public boolean equals(Object otherObject) {
        if (!super.equals(otherObject)) {
            return false;
        }

        Manager other = (Manager)otherObject;
        return bonus.equals(other.bonus);
    }

    @Override
    public int hashCode() {
        return super.hashCode() + 17 * bonus.hashCode();
    }

    @Override
    public String toString() {
        return super.toString() + "[bonus=" +bonus + "]";
    }
}

3.测试代码

package com.lin.test;

import com.lin.model.Employee;
import com.lin.model.Manager;

/**
 * 测试类
 *
 * @author linrui
 * @date 2019/03/27
 * */
public class EqualsTest {

    public static void main(String[] args) {
//        Employee alice1 = new Employee("Alice Adams", new Double(7500), 1987, 12, 15);
//        Employee alice2 = alice1;
//        Employee alice3 = new Employee("Alice Adams", new Double(7500), 1987, 12, 15);
//        Employee bob = new Employee("Bob Brandson", new Double(5000), 1989, 10, 1);
//
//        System.out.println("alice1 == alice2:" + (alice1 == alice2));
//
//        System.out.println("alice1 == alice3:" + (alice1 == alice3));
//
//        System.out.println("alice1.equals(alice3)):" + alice1.equals(alice3));
//
//        System.out.println("alice1.equals(bob)):" + alice1.equals(bob));
//
//        System.out.println("bob.toString():" + bob);
//

        Manager carl = new Manager("Carl Cracker", new Double(8000), 1987, 12, 15);
        Manager boss = new Manager("Carl Cracker", new Double(8000), 1987, 12, 15);
        boss.setBonus(new Double(5000));
        carl.setBonus(new Double(5000));
//        System.out.println("boss.toString()" + boss);
        System.out.println("carl.equals(boss):" + carl.equals(boss));
//        System.out.println("alice1.hashCode():" + alice1.hashCode());
//        System.out.println("alice3.hashCode():" + alice3.hashCode());
//        System.out.println("bob.hashCode():" + bob.hashCode());
//        System.out.println("carl.hashCode():" + carl.hashCode());


    }
}

4.使用小结:

直接看上面的测试类,注释掉的地方都是很好理解的,就不在累赘。

因为Manager中的equals方法调用了父类Employee的equals方法

所以,直接将断点打到Employee的equals()方法中,然后debug跑起来,

虽然otherObject被强制转换成了Employee,但是other并不是一个对象,而是指向otherObject对象的一个引用,而实际上otherObject是一个Manager对象。

所以,在调用otherObject.getSalary()方法的时候,实际上执行的是Manager中的方法

所以最终的输出结果是flase。

 

看明白的话自然还是好理解的,但是一开始我看的时候发现怎么想都不太对,于是就去跟踪源码,发现了是这里的问题。其实要是想简单明白,就直接将Manager中的equals方法重写为以下这个就好理解了。

@Override
    public boolean equals(Object otherObject) {
        if (this == otherObject) {
            return true;
        }
        if (otherObject == null) {
            return false;
        }
        if (getClass() != otherObject.getClass()) {
            return false;
        }

        Manager other = (Manager)otherObject;
        return bonus.equals(other.bonus);
    }

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值