1. 程式人生 > >Java之hashCode的作用和equals方法的重構規則

Java之hashCode的作用和equals方法的重構規則

ide return 一點 eset log 什麽 bsp amp person

這個是博主對hashcode的初步理解,以後加深了會再來更新:

1、hashcode是什麽?

hashcode是對象的散列碼,不同的對象幾乎不一樣,說幾乎是因為還是可以一樣的。

特點:每一個對象都有hashcode,默認的值是每一個對象的地址。

2、hashcode的作用:

博主已知的方便用戶使用散列表插入數據,我們知道,集合有兩種,list----可重復,set----不可重復。

其中set實現不可重復就需要使用到hashcode和equals方法。

散列表set是使用鏈表數組實現的,每一個列表被稱作桶,而查找表中對象的位置使用的方法是:

1)、計算對象的散列碼hashcode;

2)、公式:hashcode%桶數=索引;eg:某一個對象的散列碼是76268,有128個桶,那麽對應的這個對象的位置就是在第108個桶中。

而在插入對象到散列表中的時候使用的是同樣的過程,只是這個時候可能會發現原有的位置被占用了,桶已經滿了,這個時候就需要equals方法進行判斷是否相等。

所以:

在重構equals方法的時候一定要重構hashcode方法,不然使用散列表的時候桶都找不到,更不用說下一步的判斷是否是同一個對象了。

下面是示例代碼:

    public static void main(String[] args) {
        String hello = "hello";
        StringBuilder helloSB = new StringBuilder(hello);

        String hello2 = "hello";
        StringBuilder hello2SB = new StringBuilder(hello2);

        System.out.println("hello‘s hashcode:" + hello.hashCode());
        System.out.println("helloSB‘s hashcode:" + helloSB.hashCode());
        System.out.println("hello2‘s hashcode:" + hello2.hashCode());
        System.out.println("hello2SB‘s hashcode:" + hello2SB.hashCode());


        Set stringSet = new HashSet();
        Set sbSet = new HashSet();

        stringSet.add(hello);
        System.out.println("======" + stringSet.contains(hello2));
        stringSet.add(hello2);


        sbSet.add(helloSB);
        sbSet.add(hello2SB);


        Person person1 = new Person(1, "eke");
        Person person2 = new Person(1, "eke");

        Set personSet = new HashSet();

        personSet.add(person1);
        personSet.add(person2);


        PersonWithHashCode code1 = new PersonWithHashCode(1, "eke");
        PersonWithHashCode code2 = new PersonWithHashCode(1, "eke");

        Set codeSet = new HashSet();

        codeSet.add(code1);
        codeSet.add(code2);

        System.out.println(stringSet.size());
        System.out.println(sbSet.size());
        System.out.println(personSet.size());
        System.out.println(codeSet.size());
    }

運行結果:  

hello‘s hashcode:99162322
helloSB‘s hashcode:39219479
hello2‘s hashcode:99162322
hello2SB‘s hashcode:2031787571
======true
1
2
2
1

  

下面是PersonWithHashCode,Person和PersonWithHashCode相比只是缺少了hashCode方法。

貼這個代碼還有一點是重構了equals方法,這個方法的重構是要遵循一定規則的(圖片來自《java核心技術卷II》):

技術分享圖片

public class PersonWithHashCode {
    private int id;
    private String name;

    public PersonWithHashCode(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int hashCode() {
        return id * 24 + name.hashCode();
    }

    @Override
    public boolean equals(Object object) {
        if (object == this)
            return true;

        if (object == null)
            return false;

        if (getClass() != object.getClass())
            return false;

        PersonWithHashCode person = (PersonWithHashCode) object;
        return this.id == person.id
                && Person.StringUtils.compare(name, person.getName());
    }

    static class StringUtils {
        static boolean compare(String a, String b) {
            if (a == null && b == null)
                return true;

            if (a == null && b != null) {
                return false;
            }

            if (a != null && b == null)
                return false;

            return a.equals(b);
        }

    }

}

  

Java之hashCode的作用和equals方法的重構規則