Java中hashCode方法的理解以及此小结的总结练习(代码)

笔记:

“散列码”就是用来把一堆对象散到各自的队列里去的一种标识码。

举个形象一点的例子,一年有 365 天,从 1 编号到 365,下面我定义一种编码方法,每个人按照他生日那天的编号作为他的标识码,这样,一群人每个人就会有一个标识码。

这个标识码有什么用呢?好,下面我说,请所有单号的人站到一起,所有双号的人站在一起。此后,当我要找一个人的时候,如果知道他的编号是单号,那我只需要到前面一堆人里去找,查找效率提高了一倍。

如果我说,请编号能被 16 整除的人站到一起,被 16 除余 1 的人站到一起,被 16 除余 2 的人站到一起…… 此后,当我要找一个人的时候,查找效率就会提高到 16 倍。

这就是散列码。所以,一个好的散列码算法,配合一个适当的存储机制,就能够实现高效的存储管理。

那么,不好的散列码算法会有多糟糕呢?比如,hashCode() 返回一个常量,那么,无论什么存储机制都会退化,所有的人都站在一堆里,查找效率无法提高。不过,也就只是影响效率,不会影响“正确性”,因为散列码的本性决定了,所有的算法都不应该假设两个不同的对象必须有不同的散列码。

 总结:

EqualsTest:

package equals;

/**
 * 此程序实现了Employee类和Manager类的equals,hashCode和toString方法
 * @author 大凌轩
 *
 */
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 == 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", 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());
    }

}

Employee:

package equals;

import java.time.LocalDate;
import java.util.Objects;

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;
        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;
    }

    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.getClass())
            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(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay);
    }

    public int hashCode() {
        return Objects.hash(name, salary, hireDay);
    }

    public String toString() {
        return getClass().getName() + "[name=" + name + ", salary=" + salary + ", hireDay=" + hireDay + "]";
    }

}

Manager:

package equals;

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);
        bonus = 0;
    }

    public double getSalary() {
        double baseSalary = super.getSalary();
        return baseSalary + bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }

    public boolean equals(Object otherObject) {
        if (!super.equals(otherObject))
            return false;
        Manager other = (Manager) otherObject;
        // super.equals checked that this and other belong to the same class
        return bonus == other.bonus;
    }

    public int hashCode() {
        return super.hashCode() + 17 * new Double(bonus).hashCode();
    }

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

 

posted on 2018-08-06 21:29  大凌轩  阅读(223)  评论(0编辑  收藏  举报

导航