我正在尝试使用Guava来模拟LRU地图。
Map<K, V> map = CacheBuilder.newBuilder()
.maximumSize(maxSize)
.build() // not using a cache loader
.asMap();
但是当我尝试这样做时,我得到一个错误。
Type mismatch: cannot convert from ConcurrentMap<Object,Object> to Map<K,V>
但是,如果我使用对缓存的临时引用创建Map,它可以正常工作。
Cache<K, V> cache = CacheBuilder.newBuilder()
.maximumSize(maxSize)
.build();
Map<K, V> map = cache.asMap();
为什么这样做而第一个样本没有?
答案 0 :(得分:8)
这是Java的泛型错误 - 在这种情况下无法推断泛型类型。您应该添加<K, V>
告诉Java将新创建的缓存视为Cache<K, V>
,而不是Cache<Object, Object>
。
private static <K, V> Map<K, V> makeMap(final int maxSize) {
return CacheBuilder.newBuilder()
.maximumSize(maxSize)
.<K, V>build() // not using a cache loader
.asMap();
}
然后它会起作用:
final Map<Long, String> map = makeMap(10);
答案 1 :(得分:1)
这是我从Xaerxess的回答中得出的,用法:
private final Map<String, List<Condition>> waitersByKey=MapUtil.create(5, 1000);
MapUtil.java:
import java.util.Map;
import java.util.concurrent.TimeUnit;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalListener;
public class MapUtil {
/**
* Value for items which are unrestricted (-1)
*/
public static final int UNRESTRICTED=-1;
/**
* Create a generic map that will not exceed max size
* @param maxSize
* @return created map
*/
public static <K,V> Map<K,V> createWithMaxSize(int maxSize) {
return create(UNRESTRICTED,maxSize);
}
/**
* Create a generic map that will expire objects if not accessed within a given number of minutes
* @param expireInMins
* @return created map
*/
public static <K,V> Map<K,V> createWithExpiration(int expireInMins) {
return create(expireInMins,UNRESTRICTED,UNRESTRICTED);
}
/**
* Creates a map with an initial size. Reduces growth performance hit.
* @param initialSize
* @return created map
*/
public static <K,V> Map<K,V> createWithInitialSize(int initialSize) {
return create(UNRESTRICTED,UNRESTRICTED,initialSize);
}
/**
* Create generic map that expires values with max size
* @param expireInMins max age of unaccessed items in minutes, or UNRESTRICTED
* @param maxSize max number of items before oldest is removed, or UNRESTRICTED
* @return created map
*/
public static <K,V> Map<K,V> create(int expireInMins, int maxSize) {
return create(expireInMins,maxSize,UNRESTRICTED);
}
/**
* Create generic map that expires values with max size
* @param expireInMins max age of unaccessed items in minutes, or UNRESTRICTED
* @param maxSize max number of items before oldest is removed, or UNRESTRICTED
* @param removalListener listener called on item removal, if not null
* @return created map
*/
public static <K,V> Map<K,V> create(int expireInMins, int maxSize, RemovalListener<K, V> removalListener) {
return create(expireInMins,maxSize,UNRESTRICTED, removalListener);
}
/**
* Convenience method to build a Guava cache as generic map.
* http://stackoverflow.com/a/14730359/303442
* @param expireInMins max age of unaccessed items in minutes, or UNRESTRICTED
* @param maxSize max number of items before oldest is removed, or UNRESTRICTED
* @param initialCapacity initial size in elements, reduces growth performance hit. UNRESTRICTED for default
* @return created map
*/
public static <K,V> Map<K,V> create(int expireInMins, int maxSize, int initialCapacity) {
return create(expireInMins,maxSize,initialCapacity,null);
}
/**
* Convenience method to build a Guava cache as generic map.
* http://stackoverflow.com/a/14730359/303442
* @param expireInMins max age of unaccessed items in minutes, or UNRESTRICTED
* @param maxSize max number of items before oldest is removed, or UNRESTRICTED
* @param initialCapacity initial size in elements, reduces growth performance hit. UNRESTRICTED for default
* @param removalListener listener called on item removal, if not null
* @return created map
*/
public static <K,V> Map<K,V> create(int expireInMins, int maxSize, int initialCapacity,RemovalListener<K, V> removalListener) {
CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder();
if (expireInMins>-1)
builder.expireAfterWrite(expireInMins, TimeUnit.MINUTES);
if (maxSize>-1)
builder.maximumSize(1000);
if (initialCapacity>-1)
builder.initialCapacity(initialCapacity);
if (removalListener!=null)
builder.removalListener(removalListener);
return builder.<K,V>build().asMap();
}
}