談談java的hashcode使用場景


hashcode是在Object就已經定義了一個方法,名叫散列碼,來看看Object是怎么描述它的

    /**
     * Returns a hash code value for the object. This method is
     * supported for the benefit of hash tables such as those provided by
     * {@link java.util.HashMap}.
     * <p>
     * The general contract of {@code hashCode} is:
     * <ul>
     * <li>Whenever it is invoked on the same object more than once during
     *     an execution of a Java application, the {@code hashCode} method
     *     must consistently return the same integer, provided no information
     *     used in {@code equals} comparisons on the object is modified.
     *     This integer need not remain consistent from one execution of an
     *     application to another execution of the same application.
     * <li>If two objects are equal according to the {@code equals(Object)}
     *     method, then calling the {@code hashCode} method on each of
     *     the two objects must produce the same integer result.
     * <li>It is <em>not</em> required that if two objects are unequal
     *     according to the {@link java.lang.Object#equals(java.lang.Object)}
     *     method, then calling the {@code hashCode} method on each of the
     *     two objects must produce distinct integer results.  However, the
     *     programmer should be aware that producing distinct integer results
     *     for unequal objects may improve the performance of hash tables.
     * </ul>
     * <p>
     * As much as is reasonably practical, the hashCode method defined by
     * class {@code Object} does return distinct integers for distinct
     * objects. (This is typically implemented by converting the internal
     * address of the object into an integer, but this implementation
     * technique is not required by the
     * Java&trade; programming language.)
     *
     * @return  a hash code value for this object.
     * @see     java.lang.Object#equals(java.lang.Object)
     * @see     java.lang.System#identityHashCode
     */
    public native int hashCode();

hashcode如果沒有覆蓋重寫,那么默認是由Object導出的對象存儲地址。主要應用場景是HashMap和HashSet等等的Hash集合類里面

實例1⃣️:String的hashCode()方法

public static void main(String[] args) {
    String a1=new String("張");
    String a2=new String("張");
    String a3=new String("吳");
    HashSet<String> h1=new HashSet<>();
    h1.add(a1);
    h1.add(a2);
    h1.add(a3);
    System.out.println(h1);
}

輸出結果:

我明明add了三個對象進去,為什么HashSet里面只有兩個元素,這是因為String覆蓋了Object的hashcode()方法,我們來看看String的hashcode()

    /**
     * Returns a hash code for this string. The hash code for a
     * {@code String} object is computed as
     * <blockquote><pre>
     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
     * </pre></blockquote>
     * using {@code int} arithmetic, where {@code s[i]} is the
     * <i>i</i>th character of the string, {@code n} is the length of
     * the string, and {@code ^} indicates exponentiation.
     * (The hash value of the empty string is zero.)
     *
     * @return  a hash code value for this object.
     */
    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

String的hashcode值為每個字符chat值相加。HashSet雖然添加了三個對象,但是其中兩個對象的值是一樣的,所以HashSet只保存兩個元素。

實例2⃣️:Object的hashCode()方法

我們將實例1⃣️的中的String類型換成Object類型,代碼如下:

public static void main(String[] args) {
    Object a1=new Object();
    Object a2=new Object();
    Object a3=new Object();
    HashSet<Object> h1=new HashSet<>();
    h1.add(a1);
    h1.add(a2);
    h1.add(a3);
    System.out.println(h1);
}

輸出結果:

OK,HashSet保存了三個對象,沒問題,因為Object的hashcode默認就是對象的存儲地址

實例3⃣️自定義類覆蓋hashCode()方法

我在這里定義了一個類,代碼如下:

public class HashCodeObject {
    private int a;
    
    public int getA() {
        return a;
    }
    public void setA(int a) {
        this.a = a;
    }
    @Override
    public boolean equals(Object obj) {
        if(obj instanceof HashCodeObject){
            return this.a==((HashCodeObject)obj).getA();
        }
        return false;
    }
    @Override
    public int hashCode() {
        return this.a;
    }
}

 

然后,再將實例2⃣️的Object換成我們自己定義的類,如下

public static void main(String[] args) {
    HashCodeObject a1=new HashCodeObject();
    HashCodeObject a2=new HashCodeObject();
    HashCodeObject a3=new HashCodeObject();
    HashSet<HashCodeObject> h1=new HashSet<>();
    h1.add(a1);
    h1.add(a2);
    h1.add(a3);
    System.out.println(h1);
}

輸出結果:

注意,覆蓋hashcode()方法的同時也要覆蓋equal()方法,不然達不到效果,並且equal()和hashcode()定義必須要一致,如果equal()返回true,那么hashcode應該

具有相同的值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM