1

これが私の最初の質問ですが、必要な情報をすべて提供したいと思います。
そうでない場合は、私に知らせてください!

私の問題:
すでに処理された結果を保存するためにHashMapを追加することにより、バックトラッキングアルゴリズムを改善しようとしました。このために、そのHashMapのキー用に独自のクラスを作成しました。そこで、.equals()-メソッドと.hashCode()-メソッドを上書きしました。
しかし、このキーとその値をマップに入れようとすると、時間がかかるため、アルゴリズムの効率は、マップのないバックトラックアルゴリズムよりもさらに低くなります。
この問題を解決するために、HashMap-KeyをStringに変更し、.toString()-メソッドをkey-classに追加しました。これは非常にうまく機能し、非常に高速です。(奇妙なことに:.toString()。hashCode()は多くの負の値を生成しますが、機能しているようです)

さて、私の質問:
独自のキーを作成した場合、それは常にそれほど遅くなりますか?
私は自分でその質問に対する答えを見つけようとしましたが、見つけた唯一のシンは.hashCode()を変更するか、HashMap-Constructorのパラメーターで遊ぶことでした。
両方を試しましたが、テスト環境用に生成されたHashCodeをエクスポートしましたが、重複は見つかりませんでしたが、ハッシュコードの「適切な」方法ではありません。

これが私の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);

キーのタイプを文字列に変更し、その文字列をマップに配置すると、正常に機能します。したがって、HashKey.hashCode()メソッドと残りのアルゴリズムは正常に機能し、非常に高速です。

このHashKeyを使用するために私ができることを誰かが知っていますか?このアルゴリズムの場合、それはそれほど重要ではありませんが、将来のアルゴリズムのために知りたいです!

質問や批評家がいる場合:彼らは大歓迎です!

前もって感謝します!

クランベ

4

2 に答える 2

0

クラスはほぼ不変です。すべてのインスタンスメンバーが最終であり、クラス自体も最終である必要があります。

ただし、すべてのインスタンスメンバーが最終的なものであるため、ビルド時にハッシュコードを計算することもできます。

// 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を返します。

于 2013-01-19T16:53:55.860 に答える
0

これを試してください: -methodを単純化し、 2回以上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のコメントを参考にコードを変更しました。

于 2013-01-19T17:03:55.027 に答える