大家好我想在java中实现缓存映射,其中映射条目在给定时间后到期。
我有这样的界面,我必须实现这些方法,但我不明白实际上是如何开始的。
public class CacheMapImpl implements CacheMap<Integer, String> {
@Override
public void setTimeToLive(long timeToLive) {
}
@Override
public long getTimeToLive() {
return 0;
}
@Override
public String put(Integer key, String value) {
return null;
}
@Override
public void clearExpired() {
}
@Override
public void clear() {
}
@Override
public boolean containsKey(Object key) {
return false;
}
@Override
public boolean containsValue(Object value) {
return false;
}
@Override
public String get(Object key) {
return null;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public String remove(Object key) {
return null;
}
@Override
public int size() {
return 0;
}
}
请告诉我如何实现这些方法,如何为我开始写一点代码,请用代码更新我的cachemap接口。
答案 0 :(得分:2)
您必须使用相同的密钥管理内部地图。使用put方法将新值添加到地图中,并为内部时间映射添加值。您可以将Long存储为值,这是该值的具体时间。
然后,在后台启动一个新线程,它将检查内部地图中所有键的所有时间,并从内部地图和主地图中删除那些“旧”条目。
这是代码。我看到你的Map实现了一个接口,其中提供了一些清除过期值的方法,我知道你不需要一种自动方法来删除过期的值。所以,代码应该是这样的:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class CacheMapImpl implements CacheMap<Integer, String> {
private Map<Integer, Long> timesCache = new HashMap<Integer, Long>();
private Map<Integer, String> values = new HashMap<Integer, String>();
/** Time for the elemens to keep alive in the map in milliseconds. */
long timeToLive = 0;
@Override
public void setTimeToLive(long timeToLive) {
this.timeToLive = timeToLive;
}
@Override
public long getTimeToLive() {
return this.timeToLive;
}
@Override
public String put(Integer key, String value) {
values.put(key, value);
timesCache.put(key, System.currentTimeMillis());
return value;
}
@Override
public void clearExpired() {
// Just remove if timeToLive has been set before...
if (timeToLive > 0) {
List<Integer> keysToClear = new ArrayList<Integer>();
long currentTime = System.currentTimeMillis();
// Check what keys to remove
for (Entry<Integer, Long> e : timesCache.entrySet()) {
if ((currentTime - e.getValue().longValue()) > this.timeToLive) {
keysToClear.add(e.getKey());
}
}
// Remove the expired keys
for (Integer key : keysToClear) {
this.timesCache.remove(key);
this.values.remove(key);
}
}
}
@Override
public void clear() {
this.timesCache.clear();
this.values.clear();
}
@Override
public boolean containsKey(Object key) {
return this.values.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
return this.values.containsValue(value);
}
@Override
public String get(Object key) {
return this.values.get(key);
}
@Override
public boolean isEmpty() {
return this.values.isEmpty();
}
@Override
public String remove(Object key) {
String rto = null;
if (containsKey(key)) {
this.values.remove(key);
this.timesCache.remove(key);
rto = key.toString();
}
return rto;
}
@Override
public int size() {
return this.values.size();
}
}
答案 1 :(得分:0)
怎么样
package map;
import java.util.Map;
import lombok.Getter;
public class TimeOutCacheMap<K, V> {
Long timeout;
@Getter
private static class MapValue<V> {
private Long timeOut;
private V v;
public MapValue(Long timeout, V v) {
this.timeOut = timeout;
this.v = v;
}
}
public TimeOutCacheMap(Long timeoutInMilliSeconds, Class<? extends Map> mapClazz) {
if (timeoutInMilliSeconds > 5000000) {
throw new RuntimeException("Timeout can be upto 5000000");
}
this.timeout = timeoutInMilliSeconds;
try {
map = mapClazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Map<K, MapValue<V>> map;
public V put(K k, V v) {
if (k == null) {
throw new RuntimeException("Invalid key");
}
Long currentTime = System.currentTimeMillis();
Long timeOutValue = currentTime + this.timeout;
MapValue<V> newV = new MapValue<V>(timeOutValue, v);
MapValue<V> oldV = map.put(k, newV);
return ((oldV == null) ? null : oldV.getV());
}
public V get(K k) {
if (k == null) {
throw new RuntimeException("Invalid key");
}
Long currentTime = System.currentTimeMillis();
MapValue<V> mapValue = map.get(k);
if (mapValue!=null && mapValue.getTimeOut() != null && mapValue.getTimeOut() >= currentTime) {
return mapValue.getV();
} else {
map.remove(k);
return null;
}
}
}