为 hashmap 实现基于时间的队列
implementing time based queue for hashmap
我正在开发一个需要固定长度的 HashMap 的应用程序。最初 hashmap 是根据大小限制的,所以我使用了 LinkedHashMap 的 removeEldestEntry 方法来实现。
代码:
public class FixedLengthHashMap<K,V> extends LinkedHashMap<K,V> {
long max_length;
public FixedLengthHashMap(long max_length){
this.max_length = max_length;
}
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return this.size() > max_length;
}
}
但现在我需要根据时间在该 HashMap 上存储条目。例如,如果 hashmap 大小为两周,则 hashmap 应该在前 14 天插入条目,当在第 15 天插入新条目时,它应该删除第 1 天的条目。在第 16 天,应删除所有 2nd say 条目,依此类推。
我再次尝试了 removeEldestEntry 方法,如下所示:
public class FixedTimeHashMap<K,V> extends LinkedHashMap<K,V> {
LocalDateTime start;
public FixedTimeHashMap(){
this.start = LocalDateTime.now();
}
protected boolean removeEldestEntry(Map.Entry<K, V> eldest)
{
LocalDateTime current= LocalDateTime.now();
Long diff = ChronoUnit.SECONDS.between(start, current);
if(diff>60*60*24*14)
return true;
else
return false;
}
}
但这只会在第 14 天后为每次插入删除一个条目。在第 15 天插入新条目时,我必须删除第一天的所有条目。
如果能给点意见或建议会很有帮助。提前致谢。
LinkedHashMap 将是一个很好的起点,因为它维护插入顺序。该值需要有一个日期,因此可以将原始值包装在一些 class 中并带有日期,或者需要一个接口。
static class Dated<V> {
public final LocalDate date = LocalDate.now();
public final V value;
public Dated(V value) {
this.value = value;
}
}
Map<K, Dated<V>> map = new LinkedHashMap<>();
void insert(K key, V value) {
Dated<V> datedValue = new Dated<>(value);
LocalDate earliest = datedValue.date.minusDays(14);
Iterator<Map.Entry<K, Dated<V>> it = map.entries().iterator();
while (it.hasNext() && it.next().getValue().date.isBefore(earliest)) {
it.remove();
}
map.remove(key); // So at the end of the linked list.
map.put(key, datedValue);
}
remove
确保最新添加的内容被添加到链表的末尾,即使key已经存在。
因此迭代从最旧的元素开始,然后删除那些元素。
注:题目问的是removeEldestOnes
,是根据当前时间。这意味着当没有插入任何内容时,仍然可以删除过去超过 14 天的旧条目。
我的代码也可以用于此,但首先在插入时执行 map.remove
是必不可少的,因此集成的 insert
.
定制 collection class 我留给 OP。
我正在开发一个需要固定长度的 HashMap 的应用程序。最初 hashmap 是根据大小限制的,所以我使用了 LinkedHashMap 的 removeEldestEntry 方法来实现。
代码:
public class FixedLengthHashMap<K,V> extends LinkedHashMap<K,V> {
long max_length;
public FixedLengthHashMap(long max_length){
this.max_length = max_length;
}
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return this.size() > max_length;
}
}
但现在我需要根据时间在该 HashMap 上存储条目。例如,如果 hashmap 大小为两周,则 hashmap 应该在前 14 天插入条目,当在第 15 天插入新条目时,它应该删除第 1 天的条目。在第 16 天,应删除所有 2nd say 条目,依此类推。
我再次尝试了 removeEldestEntry 方法,如下所示:
public class FixedTimeHashMap<K,V> extends LinkedHashMap<K,V> {
LocalDateTime start;
public FixedTimeHashMap(){
this.start = LocalDateTime.now();
}
protected boolean removeEldestEntry(Map.Entry<K, V> eldest)
{
LocalDateTime current= LocalDateTime.now();
Long diff = ChronoUnit.SECONDS.between(start, current);
if(diff>60*60*24*14)
return true;
else
return false;
}
}
但这只会在第 14 天后为每次插入删除一个条目。在第 15 天插入新条目时,我必须删除第一天的所有条目。
如果能给点意见或建议会很有帮助。提前致谢。
LinkedHashMap 将是一个很好的起点,因为它维护插入顺序。该值需要有一个日期,因此可以将原始值包装在一些 class 中并带有日期,或者需要一个接口。
static class Dated<V> {
public final LocalDate date = LocalDate.now();
public final V value;
public Dated(V value) {
this.value = value;
}
}
Map<K, Dated<V>> map = new LinkedHashMap<>();
void insert(K key, V value) {
Dated<V> datedValue = new Dated<>(value);
LocalDate earliest = datedValue.date.minusDays(14);
Iterator<Map.Entry<K, Dated<V>> it = map.entries().iterator();
while (it.hasNext() && it.next().getValue().date.isBefore(earliest)) {
it.remove();
}
map.remove(key); // So at the end of the linked list.
map.put(key, datedValue);
}
remove
确保最新添加的内容被添加到链表的末尾,即使key已经存在。
因此迭代从最旧的元素开始,然后删除那些元素。
注:题目问的是removeEldestOnes
,是根据当前时间。这意味着当没有插入任何内容时,仍然可以删除过去超过 14 天的旧条目。
我的代码也可以用于此,但首先在插入时执行 map.remove
是必不可少的,因此集成的 insert
.
定制 collection class 我留给 OP。