2016-01-13 2 views
2

У нас есть библиотека коллекции java, которая возвращает дату последнего модифицированного/вставленного объекта, добавленного в коллекцию.Структура данных коллекции Java с последним измененным временем

например.

TimeBasedSet<Foo> foos = new TimeBasedSet<>(); 
foos.add(foo1); //executed at t1 
foos.add(foo2); //executed at t2 
foos.add(foo1); //executed at t3 

foos.lastModifiedDate(foo1); //returns t3 
foos.lastModifiedDate(foo2); //returns t2 
foos.insertedDate(foo1); //returns t1 
foos.insertedDate(foo2); //returns t2 
+3

никогда не видел ничего подобного, но это не сложно реализовать самостоятельно, расширяя существующую реализацию и переопределяя методы, которые изменяют набор – Leo

ответ

4

Мне не известно о какой-либо существующей реализации.

Чтобы реализовать свой собственный, просто создайте новый класс, который реализует заданный интерфейс.

public class TimeBasedSet implements Set<E> { ... } 

Вы можете создать вложенный класс (не статический) внутри этого класса для данного типа элемента значения, как это:

private class Val { 
    public E element; //public out of laziness since its nested/private. 
    public Date creationDate; 
    public Date lastModifiedDate; 
} 

Элемент Значения может хранить тип значения, вы в буквальном смысле пытаетесь (независимо от того, что E в вашей реализации интерфейса карты) вместе с метаданными во времени.

Затем, когда вы переопределяете add/get, вы вызываете set add/get и сохраняете новое время сразу после этого.

После этого вам просто понадобятся пара функций для поиска времени.

1

Уже упоминалось, что такой структуры данных нет среди существующих коллекций.

В качестве альтернативного решения я могу предложить вам простую обертку над HashMap:

import java.util.Date; 
import java.util.HashMap; 
import java.util.Map; 

class TimeBasedSet<T> { 

    private static class StorageData { 

     StorageData(Date insertionDate, Date lastModificationDate) { 
      this.insertionDate = insertionDate; 
      this.lastModificationDate = lastModificationDate; 
     } 

     Date insertionDate; 
     Date lastModificationDate; 
    } 

    private Map<T, StorageData> storage = new HashMap<>(); 

    public void add(T key) { 
     Date date = new Date(); 

     StorageData storageData = new StorageData(storage.containsKey(key) ? storage.get(key).insertionDate : date, date); 

     storage.put(key, storageData); 
    } 

    public Date getInsertionTime(Object key) { 
     return storage.containsKey(key) ? storage.get(key).insertionDate : null; 
    } 

    public Date getLastModificationTime(Object key) { 
     return storage.containsKey(key) ? storage.get(key).lastModificationDate : null; 
    } 
} 

осуществление, который показанное выше, довольно просто. Мы сохраняем все данные в HashMap, где ключ - некоторый параметризованный тип T, а значение - это класс StorageData, содержащий время вставки и время последней модификации сохраненного ключа.

В add метод мы создаем StorageData для добавления ключа. Время последней модификации всегда устанавливается на текущее время. Время вставки также устанавливается на текущее время, но если этот ключ уже находится в Map, мы обрабатываем время вставки соответствующим образом. Затем мы помещаем новую ключ-значение в Map.

Кроме того, для каждого типа даты добавляются два getters're.

0

Благодарим вас «John Humphreys - w00te» и «Edgar Rokyan».

Я проанализировал оба подхода и объединил ваши предложения по внедрению TimeBasedSet.

  1. TimeBasedSet должен реализовывать Set, так как мне нужно использовать другие методы Set, например. containsAll, addAll и т. д.
  2. Обтекание E внутри другого объекта Val усложняет реализацию. например containsAll метод требует разворачивания Val.

Детали реализации,

  1. Поддерживать внутреннюю Set internalSet и карта storageDataMap.
  2. Делегировать вызовы из размера TimeBasedSet, isEmpty, содержит и т. Д. Методы для внутреннего набора.
  3. Для добавления, addAll, remove, removeAll, keepAll и clear методы обновляют storageDataMap, а затем делегируют вызовы internalSet.
Смежные вопросы