美文网首页
equals,hashCode

equals,hashCode

作者: 很很狠的狠角色 | 来源:发表于2017-11-07 23:26 被阅读0次

    一、 equals()、hashCode()、 toString()

    如果重新定义equals方法,就必须重新定义hashCode方法。

    • Class getClass()返回包含对象信息的类对象
    • boolean equals(Object otherObject)比较两个对象是否相等,如果两个对象指向同一块存储区域,方法返回true;否则方法返回false。在自定义类中,应该覆盖这个方法。
    • String toString() 返回描述该对象的字符串。在自定义类中,应该覆盖这个方法。
    • Class getSuperclass() 一Class对象的形式返回这个类的超类信息。
    1. EqualsTest.java
    package equals;
    /**
     * This program demonstrates the equals method
     * @version 1.80 2017-11-03
     * @author Mr.Ding
     *
     */
    public class EqualsTest {
        public static void main(String[] args){
            Employee alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15);
            Employee alice2 = alice1;
            Employee alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15);
            Employee bob = new Employee("Bob Brandson", 50000, 1989, 10, 1);
            System.out.println("alice1 == alice2: " + (alice1 == alice2));
            System.out.println("alice1 == alice2: " + (alice1 == alice2));
            System.out.println("alice1 == alice3: " + (alice1 == alice3));
            System.out.println("alice1.equals(bob): " + alice1.equals(bob));
            System.out.println("bob.toString(): " + bob);
            
            Manager carl = new Manager("Carl Cracker", 80000, 1987, 12, 15);
            Manager boss = new Manager("Carl Cracker", 80000, 1987, 12, 15);
            boss.setBonus(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());
        }
    }
    
    1. Employee.java
      java.util.Objects;
      static boolean equals(Object a, Object b)
      Objects.equals(this.name, other.name)
      如果a和b都为null,返回true;如果只有其中之一为null,则返回false;否则返回a.equals(b)。
    package equals;
    
    import java.util.Date;
    import java.util.GregorianCalendar;
    import java.util.Objects;
    
    public class Employee {
        private String name = "";
        private double salary = 0.0;
        private Date hireDay;
        
        public Employee(String name, double salary, int year, int month, int day){
            this.name = name;
            this.salary = salary;
            GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);
            hireDay = calendar.getTime();
        }
        
        public String getName(){
            return this.name;
        }
    
        public double getSalary() {
            return this.salary;
        }
        //better returns hireDay's clone
        public Date getHireDay() {
            return this.hireDay;
        }
        
        public void raiseSalary(int byPercent){
            double raise = this.salary * byPercent / 100;
            this.salary += raise;
        }
        
        public boolean equals(Object otherObject){
            //a quick test to see if the objects are identical
            if(this == otherObject){
                return true;
            }
            
            //must return false if the explicit parameter is null
            if(otherObject == null){
                return false;
            }
            
            //if the classes don't match,they can't be equal
            if(getClass() != otherObject){
                return false;
            }
            
            //now we know otherObject is a non-null Employee
            Employee other = (Employee) otherObject;
            
            //test whether the fields have identical values
            return Objects.equals(this.name, other.name) && salary == other.salary && Objects.equals(this.hireDay, other.hireDay);
        }
        
        public int hashCode(){
            return Objects.hash(this.name, this.salary, this.hireDay);
        }
        
        //better choice is getClass() instead of class_name
        public String toString(){
            return getClass().getName() + "[name= " + this.name + ", salary=" + this.salary + ", hireDay=" + this.hireDay + "]";
        }
    }
    
    1. Manager.java
    public boolean equals(Object otherObject){
            //super.equals checked that this and other belong to the same class
            if(!super.equals(otherObject)){
                return false;
            }
            Manager other = (Manager) otherObject;
            return this.bonus == other.bonus;
        }
    

    在子类中定义equals方法时,首先调用超类的equals。如果检测失败,对象就不可能相等。如果超类中的域都相等,就需要比较子类中的实力域。

    package equals;
    
    public class Manager extends Employee{
        private double bonus = 0.0;
        
        public Manager(String name, double salary, int year, int month, int day){
            super(name, salary, year, month, day);
            bonus = 0.0;
        }
        
        public double getSalary(){
            double baseSalary = super.getSalary();
            return baseSalary + this.bonus;
        }
        
        public void setBonus(double bonus){
            this.bonus = bonus;
        }
        
        public boolean equals(Object otherObject){
            //super.equals checked that this and other belong to the same class
            if(!super.equals(otherObject)){
                return false;
            }
            Manager other = (Manager) otherObject;
            return this.bonus == other.bonus;
        }
        
        public int hashCode(){
            return super.hashCode() + 17 * new Double(bonus).hashCode();
        }
        
        public String toString(){
            return super.toString() + "[bonus=" + bonus + "]";
        }
    }
    
    1. 运行结果


    2. 散列码(hash code)是由对象导出的一个整型值。散列码是没有规律的。如果x和y是两个不同的对象,x.hashCode()与y.hashCode()基本上不会相同。字符串的散列码是由内容导出的。
        equals()比较的是两个对象的值是否相等;==表示的是两个对象的地址是否相等。==比较堆内存的值是否相等(对象地址存放在堆内存),equals()比较栈内存的值(对象的值存在于栈内存中)。但是String是个例外,String有个”常量池“。String a = "abc";String b = "abc";a==b是返回true的。String a = "abc";String b = new String("abc");a==b是返回false的,a和b不是一个对象,地址不相等。
      *****可以用javac编译得到class文件,然后javap -verbose class查看字节码,如果是常量就是一样,如果不是,是通过StringBuilder实现的“+”,就是新对象。




      字节码里显示是“//String abc” ,证明a,b是同一个对象,a==b返回的是true。

    相关文章

      网友评论

          本文标题:equals,hashCode

          本文链接:https://www.haomeiwen.com/subject/vscjmxtx.html