Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当值大于x时,从贴图中删除的最佳方法是什么_Java_Date_Map_Concurrency - Fatal编程技术网

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);
            }
        }
    }
}