Java 当值大于x时,从贴图中删除的最佳方法是什么
我正在尝试创建一个Java 当值大于x时,从贴图中删除的最佳方法是什么,java,date,map,concurrency,Java,Date,Map,Concurrency,我正在尝试创建一个映射,它可以保存值直到日期值>1天 执行此操作的最佳方法是使用ConcurrentHashMap,然后创建一个线程,每隔一分钟左右迭代映射一次,然后删除早于1天的值,还是有更好的方法 为了澄清,收到的日期消息将不是当前时间,它可以是前一个时间 谢谢编辑:好的,我已经编辑了下面的所有内容,使用了一个可选的,因为番石榴的缓存不喜欢可调用的或缓存加载程序返回空值,您想将其用作一个映射,其中可能缺少与键相关的值 用番石榴汁 我可能会创建一个包含HashMap的自定义类,以及同样存储在H
映射
,它可以保存值直到日期值>1天
执行此操作的最佳方法是使用ConcurrentHashMap
,然后创建一个线程,每隔一分钟左右迭代映射一次,然后删除早于1天的值,还是有更好的方法
为了澄清,收到的日期消息将不是当前时间,它可以是前一个时间
谢谢编辑:好的,我已经编辑了下面的所有内容,使用了一个
可选的,因为番石榴的缓存不喜欢可调用的或缓存加载程序
返回空值
,您想将其用作一个映射
,其中可能缺少与键相关的值
用番石榴汁
我可能会创建一个包含HashMap的自定义类,以及同样存储在HashMap中的对象的优先级队列。当对象太旧时,优先级队列按系统时间排序
在此之后,您可以拥有某种类型的内部私有线程,该线程将一直休眠,直到下一次需要从队列中删除优先级队列中的第一个对象以及从HashMap中删除该对象为止。不需要在HashMap中循环,也不需要以一定的速率检查值
如果您不需要自己实现,请使用第三方库解决方案,如另一个答案。您可以这样编写自己的地图:
public class DateHashMap implements Map<String, Date>{
..
@Override
public String put(Date key, String value) {
// Check date...
}
..
}
公共类DateHashMap实现映射{
..
@凌驾
公共字符串put(日期键、字符串值){
//检查日期。。。
}
..
}
真诚地
Max您可以对ConcurrentHashMap进行子类化,或者更好的方法是,包装映射并删除它找到的任何早于一天的条目。这可以在没有额外线程的情况下完成
另一种选择是将条目添加到优先级队列中,并从最早的条目中删除。我过去考虑过这一点,并得出了一些不同的解决方案。最终,我认为您将想要实现一个Map或者扩展一个现有的Map实现。使用这个实现应该可以得到您想要的,您需要创建一个线程来调用execute方法
public class DateKeyedMap<V> extends HashMap<Date, V> {
public void evictOlderThan (Date dateToDelete) {
for (Date date : keySet()) {
if (date.compareTo(dateToDelete) <= 0) {
remove(date);
}
}
}
}
公共类DateKeyedMap扩展HashMap{
公共无效驱逐者(日期删除){
for(日期:keySet()){
如果(date.compareTo)到(dateToDelete),听起来像是在创建定时缓存。我可以建议使用ehcache吗?(缓存逐出很棘手。)“日期值>1天”是什么意思?日期已超过1天,因此实际缓存的值是字符串
s,而不是日期
s?不,我需要存储字符串->日期(用户ID和收到消息的日期)-我不想保留日期超过一天的条目AHHH完美这看起来正是我所需要的,非常感谢-但是,有一个问题,这只适用于输入时间,还是我可以根据字段将其指定为删除?我同意,除非收到日期消息
始终是当前时间。OP应该澄清是否需要添加解决方案。它并不总是当前时间。对不起,我删除了我的评论。但我认为现在已经很清楚了。如果它不总是当前时间,此解决方案将不适用于您。不错(对于自定义解决方案,而不是使用缓存),我建议使用DelayQueue而不是PriortyQueue,因为它是基于时间设计的。要点是在插入后1天从映射中删除,而不是阻止基于日期的插入。
Cache<String, Optional<Date>> cache = new SimpleForwardingCache<>(grapsh){
public Optional<Date>get(String key, Callable<Optional<Date>> valueLoader){
Optional<Date> result = delegate().get(key, valueLoader);
if (!result.isPresent() || olderThanADay(result.get()))
return Optional.absent();
else
return result;
}
// since you don't really need a valueLoader you might want to add this.
// this is in place of the LoadingCache, if use LoadingCache use
// ForwardingLoadingCache
public Date get(String key){
return get(key,
new Callable<Optional<Date>>(){
public Date call(){return Optional.absent();}
}
}
}
public class DateHashMap implements Map<String, Date>{
..
@Override
public String put(Date key, String value) {
// Check date...
}
..
}
public class DateKeyedMap<V> extends HashMap<Date, V> {
public void evictOlderThan (Date dateToDelete) {
for (Date date : keySet()) {
if (date.compareTo(dateToDelete) <= 0) {
remove(date);
}
}
}
}
public class DateValuedMap<K> extends HashMap<K, Date> {
public void evictOlderThan (Date dateToDelete) {
for (Date date : values()) {
if (date.compareTo(dateToDelete) <= 0) {
remove(date);
}
}
}
}