具有上次修改时间的Java集合数据结构

时间:2016-01-13 20:26:52

标签: java data-structures collections guava apache-commons

我们是否有一个java集合库,它返回添加到集合中的对象的lastmodified / inserted日期。

e.g。

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 个答案:

答案 0 :(得分:4)

我不知道任何现有的实施方式。

要实现自己的,只需创建一个实现set接口的新类。

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

value元素可以存储您实际存储的值类型(无论地图接口实现中的E是什么)以及时间元数据。

然后当你覆盖add / get时,你会调用set add / get并在此之后存储新的时间。

之后,您只需要几个函数来查找时间。

答案 1 :(得分: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中,其中key是参数化类型T,value是StorageData类,包含存储密钥的插入时间和最后修改时间。

add方法中,我们为添加的密钥创建StorageData。上次修改时间始终设置为当前时间。插入时间也设置为当前时间,但如果此键已在Map中,我们会适当地处理插入时间。然后我们将新的键值对放入Map

每种类型的日期都添加了两个吸气剂。

答案 2 :(得分:0)

谢谢你“John Humphreys - w00te”和“Edgar Rokyan”。

我分析了这两种方法,并结合了你的建议来实现TimeBasedSet。

  1. TimeBasedSet应该实现Set,因为我需要使用其他Set方法,例如containsAll,addAll等。
  2. 将E包装在另一个对象中Val使实现变得复杂。例如containsAll方法需要展开Val。
  3. 实施细节

    1. 维护内部Set internalSet和Map storageDataMap。
    2. 将来自TimeBasedSet size,isEmpty,包含etc方法的调用委托给internalSet。
    3. 对于add,addAll,remove,removeAll,retainAll和clear方法更新storageDataMap,然后将调用委托给internalSet。