0

日付を表す1つのDateWrapperが必要です(Hibernateの永続性のために構築されていますが、これは別の話です)-せいぜい同じ日付で同時に存在します。

衝突とハッシュの適切なキーについて少し混乱しています。私はDateWrapperオブジェクトのファクトリを書いています。他の人が行っているのを見たように、解析された日付のミリ秒をキーとして使用することを考えました。しかし、もし衝突したらどうなるでしょうか?. ミリ秒は常に互いに異なりますが、内部テーブルは存在する可能性のある Long よりも小さい場合があります。ハッシュ マップに衝突が発生すると、equals が使用されますが、Long から 2 つの異なるオブジェクトをどのように区別できるでしょうか? たぶん、挿入したい値を削除(上書き)するのはputメソッドです...では、このコードは安全ですか、それともバグですか??

package myproject.test;

import java.util.HashMap;
import java.util.Map;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import myproject.utilities.DateWrapper;

public class DateWrapperFactory {

    static Map <Long, DateWrapper> cache = new HashMap<Long, DateWrapper>();
    static DateTimeFormatter parser =
        DateTimeFormat.forPattern("yyyy-MM-dd");

    static DateWrapperFactory instance = new DateWrapperFactory();

    private DateWrapperFactory() {
    }

    public static DateWrapperFactory getInstance() {
        return instance;
    }


    public static DateWrapper get(String source) {
        DateTime d = parser.parseDateTime(source);
        DateWrapper dw = cache.get(d.getMillis());
        if (dw != null) {
            return dw;
        } else {
            dw = new DateWrapper(d);
            cache.put(d.getMillis(), dw);
            return dw;
        }
    }

}

package myproject.test;

import org.joda.time.DateTime;

public class DateWrapper {

    private DateTime date;

    public DateWrapper(DateTime dt) {
        this.date = dt;
    }

}
4

4 に答える 4

0

equals()、値ではなく、Longキーで呼び出されます。あなたは大丈夫です。

于 2010-11-15T19:32:25.733 に答える
0

HashMap を使用すると、特定のキー値 (たとえば、この場合は Long) の下に 1 つのエントリのみを格納できます。

余談ですが、同時実行の可能性がある場合は、非アトミックな get/if/put 呼び出しの代わりにConcurrentHashMap とputIfAbsent()を使用することをお勧めします。

于 2010-11-15T19:27:42.150 に答える
0

必要な実際のオブジェクトをマップ キーとして使用し、HashMapそれらのオブジェクトのハッシュコード (およびキーの実装equalshashCodeそのコントラクトによる) の処理の詳細を処理する場合、ハッシュコードが存在しても問題はありません。同じバケットにハッシュされたすべてのエントリを直線的に検索する必要があるため、パフォーマンスが低下する可能性があります。

衝突の主題が発生した他の質問の問題は、キーであるはずの実際のオブジェクトを使用するのではなく、そのオブジェクトのハッシュコードをキー自体として使用していたことです。これは正しくなく、誤った動作につながる可能性がありました....マップ内の特定のキーの値を検索すると、結果は、たまたま持っている完全に異なるキーに実際にマップされる値である可能性があります。同じハッシュコード。

この話の教訓は、キーのハッシュコードではなく、実際のキーまたは明らかに同等のもの (この場合のミリ秒など) をキーとして使用することです。DateTimeHashMap、ハッシュコードで必要なことを行います。

于 2010-11-15T20:35:01.957 に答える
0

これで最終的に達成しようとしていることを考えると、それほど生産的ではないようです。データベース インデックスと呼ばれる、高速検索と一意性の強制のために特別に設計された、高度に最適化されたデータ構造があります。また、非常に堅牢なメモリ内キャッシュと L2 キャッシュが、Hibernate から既に用意されています。ちなみに、静的フィールドに HashMap を配置するというスレッドセーフの問題はありません。

その番号をデータベースの ID 列の値にして、堅牢なプラットフォーム テクノロジに任せて、すばやく見つけてキャッシュしてみませんか? メモリ内の L2 キャッシュ ヒットは、実際には HashMap よりもはるかに遅くはありません。違いが意味のあるホットスポットの 1 つになるアプリケーションは非常にまれです。

于 2010-11-15T20:57:44.443 に答える