簡體   English   中英

自定義HashMap-Key(Java)會極大降低性能

[英]custom HashMap-Key (Java) slows down performance extremely

這是我的第一個問題,但我希望我會提供所有必要的信息。
如果沒有,請告訴我!

我的問題:
我試圖通過添加一個HashMap來存儲已經處理的結果來改善我的回溯算法。 為此,我為該HashMap的鍵創建了自己的類。 在這里,我重寫了.equals()-和.hashCode()-方法。
但是,如果我嘗試將此密鑰及其值放入地圖中,則會花費很多時間,因此該算法的效率甚至比沒有地圖的回溯算法還要低。
為了解決該問題,我將HashMap-Key更改為String,並將.toString()方法添加到我的鍵類中。 這工作得很好並且非常快。 (奇怪的是:.toString()。hashCode()產生很多負值,但似乎可以正常工作)

現在我的問題:
如果您創建自己的密鑰,是否總是會減慢這么多速度?
我試圖自己找到該問題的答案,而我發現的唯一的問題是更改.hashCode()或使用HashMap-Constructor的參數。
我都嘗試了這兩種方法,並且將生成的HashCodes導出到我的測試環境中,但是沒有發現任何重復項,盡管我知道,這不是哈希碼的“好”方法!

這是我的HashKey-Class的副本(變量名和方法已更改):

public class HashKey {
    private final int int0, int1, int2;

    public HashKey(int int0, int int1, int int2) {
        this.int0 = int0;
        this.int1 = int1;
        this.int2 = int2;
    }

    public int getInt0() {
        return this.int0;
    }

    public int getInt1() {
        return this.int1;
    }

    public int getInt2() {
        return this.int2;
    }

    @Override
    public int hashCode() {
        final int prime1 = 107;
        final int prime2 = 227;
        final int prime3 = 499;
        int result = 1;
        result = prime1 * result + this.int2;
        result = prime2 * result + this.int1;
        result = prime3 * result + this.int0;
        return result;
     }

    @Override
    public String toString() {
        return "Int0: " + this.int0 + " Int1: " + int1 + " Int2: " + int2;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof HashKey) {
            boolean eq0, eq1, eq2;
            eq0 = this.int0 == ((HashKey) obj).getInt0();
            eq1 = this.int1 == ((HashKey) obj).getInt1();
            eq2 = this.int2 == ((HashKey) obj).getInt2();
            if (eq0 && eq1 && eq2) {
                return true;
            }
        }
        return false;
    }
}  

在我的主要班級中,我使用以下代碼:

HashMap<HashKey, List<Object>> storedResults = new HashMap<HashKey, List<Object>>();  

int x1,x2,x3;  
Object obj;  

// later in a method:

storedResults.put(new HashKey(x1,x2,x3), obj);

如果我將鍵的類型更改為String並將該String放入Map中,則可以正常工作! 因此,HashKey.hashCode()方法和該算法的其余部分都可以正常工作並且非常快。

有人知道,我可以使用此HashKey嗎? 對於此算法,它並不那么重要,但我想在以后的算法中了解它!

如有任何問題或批評:非常歡迎!

提前致謝!

克魯姆貝

您的類幾乎是一成不變的:您的所有實例成員都是最終成員,只是類本身也必須是最終成員。

但是由於所有實例成員都是最終成員,因此您還可以在構建時計算哈希碼:

// Add as member:
private final int hashCode;

public HashKey(int int0, int int1, int int2) {
    this.int0 = int0;
    this.int1 = int1;
    this.int2 = int2;
    hashCode = // calculate hash code here
}

public int hashCode()
{
    return hashCode;
}

順便說一句,否定的哈希碼沒什么好擔心的。 .hashCode()返回一個int值。

嘗試以下操作:簡單地使用equals(..)方法,並且不要多次計算hashCode

public final class HashKey {
    private final int int0, int1, int2;
    private final int hashCode;

    public HashKey(int int0, int int1, int int2) {
        this.int0 = int0;
        this.int1 = int1;
        this.int2 = int2;
        hashCode=107*int0+227*int1+499*int2;
    }

    @Override
    public final int hashCode() {
        return hashCode;
    }

    @Override
    public final boolean equals( finalObject obj) {
        if (!obj instanceof HashKey)
            retun false;
        HashKey other = (HashKey)obj;
        return int0 == other.int0 && int1 == other.int1 &&  int2 == other.int2;
    }
}  

參考fge的注釋,我更改了代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM