I am trying to create a Map<String, Date>
that can hold values until the date value > 1 day old.
Is the best approach to do this to use a ConcurrentHashMap
and then create a thread which iterates the map once every minute or so and then remove the values older than 1 day, or, is there a better approach to doing this?
For clarification the date message received will not be the current time, it can be a time previous
Thanks
EDIT: OK, so I have edited all of the below to use an Optional<Date>
because Guava's caches don't like the Callable
or CacheLoader
to return null
and you want to use this as a Map
where the value associated with a key may be absent.
Use Guava's Cache
Cache<Key, Graph> graphs = CacheBuilder.newBuilder()
.expireAfterWrite(1, TimeUnit.DAYS)
.build();
Loading Cache would be...
LoadingCache<String, Optional<Date>> graphs = CacheBuilder.newBuilder()
.expireAfterWrite(1, TimeUnit.DAYS)
.build(
new CacheLoader<String, Optional<Date>>() {
public Optional<Date>load(Stringkey) throws AnyException {
return Optional.absent();
}
});
Ok, so I think what you want if the Date may have been in the past is to wrap the above Cache
in a ForwardingCache.SimpleForwardingCache
. You then overload the get
method to return null
if the Date value is older than a day.
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();}
}
}
}
I would probably create a custom class that contains a HashMap, as well as a priority queue of the objects that are also stored in the HashMap. The priority queue is ordered by the system time when the object is too old.
After that, you can have an internal private thread of some kind that sleeps until the next time the first object in the priority queue needs to be removed from the queue and also removed from the HashMap. No need to loop through the HashMap, or check values at a certain rate.
If you don't need to implement it yourself go with a third party library solution like the other answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With