私は、キャッシュのマップからキャッシュオブジェクトを要求できる(単純な)キャッシュソリューションを開発中です。 Cacheオブジェクトは基本的にMapと同様に、オブジェクトにアクセスして格納するためのキーと値とメソッドを持っています。Java generics - (型付き)マップのマップ
私は以下の解決策を思いつきましたが、わかるように、get()はネストされたオブジェクトのタイプが何であるかを知ることができないため、キャストを含んでいます。
private final Map<String, Cache<?, ?>> caches = new HashMap<String, Cache<?, ?>>();
public <K, V> Cache<K, V> getOrCreateCache(String identifier) {
if (caches.containsKey(identifier)) {
return (Cache<K, V>) caches.get(identifier);
} else {
Cache<K, V> cache = new CacheImpl<K, V>();
caches.put(identifier, cache);
return cache;
}
}
private void test() {
Cache<String, String> strCache = getOrCreateCache("string cache");
strCache.set("key", "value");
}
さて、私の質問:
- はこれがある限りにClassCastExceptionsが適切に処理されているとして、 '安全' なアプローチですか? (おそらくそれらをキャッチし、それらをカスタム例外クラスにパックする)
- 「安全な」代替手段はありますか?私がそれらを好き、キャストを嫌うのでジェネリックで、可能な限り、1つ。
- (直接関係はありません)このスレッドセーフですか?私はそうではないと思うが、その後、私は糸を引く専門家ではない。全体のメソッドを同期させるだけで十分ですか、それとも半ダースのクライアントでオーバーヘッド/ロッキングが多すぎるのでしょうか?そのためのすてきな解決策はありますか?
編集:たくさんの回答、ありがとう!
Cache<String, String> someCache = service.getOrCreateCache(cacheIdentifier);
someCache.set("asdf", "sdfa");
Cache<String, Integer> someCacheRetrievedAgain = service.getOrCreateCache(cacheIdentifier);
System.out.println(someCacheRetrievedAgain.get("asdf")); // prints "sdfa". No errors whatsoever. Odd.
私は素早く並べ替えの識別子、素敵なトリックを構成するArrayListの拡張子を覚えておくのが好きです。私はあなたの解決策を試してみます。 – fwielstra
それを試した後:私はあなたのソリューションが大好きです。異なるタイプのキャッシュオブジェクトを取得しようとすると、新しいキャッシュオブジェクトが返されます。エレガント。キャッシュ識別子オブジェクトは、変更されない不変のスラッシュであるため、クライアントに永続的に格納することもできます。 – fwielstra
スレッドセーフソリューションのためにcom.google.common.collect.MapMaker.makeComputingMapを使用することを検討してください。メモリや時間を節約したい場合は、ArrayListを独自のクラスに置き換えます(hashCodeとequalsの実装を忘れないでください)。 – maaartinus