реализация очереди на основе времени для hashmap - PullRequest
0 голосов
/ 05 июня 2018

Я работаю над приложением, в котором мне нужна фиксированная длина для HashMap.Первоначально хеш-карта была ограничена в зависимости от размера, поэтому для этого я использовал метод removeEldestEntry LinkedHashMap.

Код:

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 в зависимости от времени.Например, если размер хеш-карты равен двум неделям, в хеш-карту должны быть вставлены записи в течение первых 14 дней, а при вставке новой записи на 15-й день следует удалить записи 1-го дня.И на 16-й день все записи второго слова должны быть удалены и так далее.

Я снова попробовал метод 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-го дня.Я должен удалить все записи 1-го дня, когда новая запись вставлена ​​на 15-й день.

Если вы можете дать несколько советов или предложений, это будет очень полезно.Заранее спасибо.

1 Ответ

0 голосов
/ 05 июня 2018

LinkedHashMap был бы хорошей отправной точкой, поскольку он поддерживает порядок вставки.У значения должна быть дата, поэтому возможно оберните исходное значение в каком-либо классе датой или используйте интерфейс.

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 гарантирует, что последнее добавление будет добавлено в концесвязанный список, даже если ключ уже существовал.

Следовательно, итерация начинается с самых старых элементов и удаляет их.

Примечание: Вопрос задан на removeEldestOnes, исходя из текущего времени.Это означает, что когда ничего не вставлено, можно все еще удалить старые записи более чем 14 дней назад.

Мой код также может быть использован для этого, но сначала необходимо выполнить map.remove на вставке, поэтомувстроенный insert.

Создание собственного класса коллекции я оставляю в ОП.

...