天天看點

hashCode()與equals()連用

before

package com.example.demo.model;

public class Before {

    private String name = "稍後123";
    private Short age = 2;

    public Before(String name, Short age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object object){
        if(object instanceof Before){
            String tempName = ((Before)object).name;
            Short tempAge = ((Before)object).age;
            return this.name.equals(tempName)&&this.age.equals(tempAge);
        }
        return  false;
    }
}
           
package com.example.demo;

import com.example.demo.model.After;
import com.example.demo.model.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {

    @Test
    public void contextLoads() {
        HashSet<Before> hashSet = new HashSet<>();
        //生成臨時變量1
        Before before1 = new Before("稍等123",(short)2);
        //生成臨時變量2
        Before before2 = new Before("稍等123",(short)2);
        //添加同一對象
        hashSet.add(before1);
        hashSet.add(before2);
        System.out.println("添加同一對象後,HashSet大小:"+hashSet.size());

    }

}
           

列印 添加同一對象後,hashSet大小:2

現象:任何類都是從object繼承而來,如果沒有重寫equals()方法,預設比較的是對象類的位址。同樣如果沒有重寫hashCode()方法,hash值也是根據對象位址來計算的。判斷兩個對象是否相等依據的是是否有相同的hashCode值和equals值。漏寫任何一個都有可能出現意外結果

解決:同時重寫equals()方法和hashCode()方法

after

package com.example.demo.model;

public class After {
    private String name = "稍等123";
    private Short age = 1;

    public After(String name, Short age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Short getAge() {
        return age;
    }

    public void setAge(Short age) {
        this.age = age;
    }

    //重寫hashCode方法
    @Override
    public int hashCode() {
        //第一步設定平衡因子
        final int balanceFactor = 17;
        int result = balanceFactor;
        //第二步計算基本類型的hash值
        result = result*balanceFactor+age;
        //第三步計算非基本類型成員變量hash值
        return result*balanceFactor+name.hashCode();
    }

    //重寫equals方法
    @Override
    public boolean equals(Object object){
        if(object instanceof After){
            String tempName = ((After)object).name;
            Short tempAge = ((After)object).age;
            return this.name.equals(tempName)&&this.age.equals(tempAge);
        }
        return  false;
    }
}
           
package com.example.demo;

import com.example.demo.model.After;
import com.example.demo.model.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {

    @Test
    public void contextLoads() {
        HashSet<After> hashSet = new HashSet<>();
        //生成臨時變量1
        After after1 = new After("稍等123",(short)1);
        //生成臨時變量2
        After after2 = new After("稍等123",(short)1);
        //添加同一對象
        hashSet.add(after1);
        hashSet.add(after2);
        System.out.println("添加同一對象後,HashSet大小:"+hashSet.size());

        //直接删除
        hashSet.remove(after2);
        System.out.println("直接删除對象後,HashSet大小:"+hashSet.size());
        //修改參與計算的hashCode的屬性後再删除
        hashSet.add(after1);
        after1.setName("3244DJSJ");
        hashSet.remove(after1);
        System.out.println("修改參與計算hashCode的屬性後,再删除對象,HashSet大小:"+hashSet.size());
        //清空hashSet
        hashSet.clear();
        System.out.println("清空hashSet,HashSet大小:"+hashSet.size());
    }

}