我有一個快取類,我用 2 HashMaps 來保存快取。
我希望能夠選擇給定key的型別別的正確地圖,以便:
- 如果
key是 Long,則從 map 中獲取值longKeyCache - 如果
key是字串,則從 map 獲取值stringKeyCache。
(假設用戶只會傳入 Long 或 String 鍵)
為此,我構建了 function getMapToUse。
問題是我必須在沒有任何型別限制的情況下將其回傳型別宣告為 Map 。只有這樣,函式才能正確編譯,我才能使用回傳的映射將快取存盤在后續代碼 ( mapToUse.put(key, value)) 中。
代碼有效,但我從 IDE 收到警告 - Raw use of parameterized class 'Map'
有沒有辦法解決這個警告?提前致謝。
public class CacheManager {
private final Map<Long,String> longKeyCache = new WeakHashMap<>();
private final Map<String,Integer> stringKeyCache = new WeakHashMap<>();
public <K, V> V getCache(K key, Function<K, V> valueLoader) {
Map<K, V> mapToUse = getMapToUse(key);
return Optional.ofNullable(mapToUse.get(key))
// cache miss
.orElseGet(() -> {
V value = valueLoader.apply(key);
mapToUse.put(key, value);
return value;
});
}
// warning: Raw use of parameterized class 'Map'
private <K> Map getMapToUse(K key) {
if (key instanceof Long) {
return longKeyCache;
} else {
return stringKeyCache;
}
}
}
uj5u.com熱心網友回復:
如果您想保留這種設計(CacheManager即“知道”具有不同型別鍵和值的兩個映射),那么您將不得不將映射轉換為Map<K, V>. 無法逃避這一點,因為編譯器將無法猜測實際的型別。
您將意識到泛型的目的之一是允許實作可以使用各種型別的相同功能,但同時應用型別安全檢查。
該方法getCache( K, Function<K, V> )正在回傳V,這意味著它V可以是Integer或String。但是哪一個??編譯器必須在呼叫方法的地方歸結為一個。
所以,這是我將如何實作這一點:因為涉及到一個小的和已知的映射鍵/值型別集,泛型可能不是這樣的。相反,我會簡單地使用多載方法。原因:呼叫者仍然具有一致的 API,即編譯時型別檢查,這是泛型的主要目標。
public class CacheManager{
private final Map<Long,String> longKeyCache = new WeakHashMap<>();
private final Map<String,Integer> stringKeyCache = new WeakHashMap<>();
public String getCache( Long key, Function<Long, String> valueLoader) {
return Optional.ofNullable( longKeyCache.get(key) )
// cache miss
.orElseGet(() -> {
String value = valueLoader.apply(key);
longKeyCache.put(key, value);
return value;
});
}
public Integer getCache( String key, Function<String, Integer> valueLoader) {
return Optional.ofNullable( stringKeyCache.get(key) )
// cache miss
.orElseGet(() -> {
Integer value = valueLoader.apply(key);
stringKeyCache.put(key, value);
return value;
});
}
/* Testing code from here on. */
public static void main( String[] args ){
CacheManager cm = new CacheManager();
cm.addTestData();
System.out.println( cm.getCache( 200L, k -> k.toString() ) );
System.out.println( cm.getCache( "500S", k -> 800 ) );
System.out.println( cm.getCache( "900", k -> 900 ) );
}
private void addTestData() {
longKeyCache.put( 200L, "200S" );
longKeyCache.put( 201L, "201S" );
stringKeyCache.put( "500S", 500 );
stringKeyCache.put( "501S", 501 );
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/327303.html
上一篇:是什么讓Arraylist成為Java中沒有的泛型型別和陣列?
下一篇:像這樣添加水印的圖片
