3

我需要存储一组数据结构,这些数据结构由时间段(开始、结束)和这段时间的计数器定义,其中包含一些复杂的计算结果。数据结构的简化定义如下:

public class CounterBag {
    private Period period;   // collection key
    private Counter counter;
    // accessors
    // ...
}

Period很简单:

public class Period {
    public DateTime start;
    public DateTime end;
    // accessors
    // ...
}

我需要一个包含CounterBagdistinct 定义的对象的集合Periods。该集合需要通过 提供有效的查找(这是捕获!)long timeInMillis,所以HashMap这不是一个真正的选择,因为我不想覆盖equalshashcodeCounterBag我需要它们两者)。集合需要按Period(按结束日期)排序。Periods 具有灵活的持续时间,执行查找的部分不知道。

我想知道在 java 标准 API 或一些开源库中是否有一个开箱即用的集合可以帮助我解决它?某种排序集或排序映射,可以实现按日期进行有效查找。按日期查找将返回日期在CounterBag其中Period的 a。

感谢您的建议。

4

5 回答 5

0

您可以使用 TreeMap 作为它的排序集合(这使得查找高效)

如果您的经期有固定间隔(这是最简单的形式),则您不需要这样的集合。您可以为每个间隔设置一个计数器。例如int[]

于 2012-05-13T13:42:01.283 回答
0

我建议一个TreeMap<Long, CounterBag>. 您可以使用以下NavigableMap界面访问它:

NavigableMap<Long, CounterBag> map = new TreeMap<Long, CounterBag>();
map.put(bag.period.end.toMillis(), bag); // Get end DateTime as a Long


long lookupLong = 10000L; // or whatever

/*
 * Retrieves the greatest Bag whose Period's end is
 * less than or equal to the Long
 */
CounterBag newBag = map.floorEntry(lookupLong).getValue();
于 2012-05-13T15:29:45.710 回答
0

我只想扩展@Peter Lawrey 的答案,为您的 CounterBag 使用带有自定义比较器的 TreeMap。

此比较器将确保返回范围内的 CounterBag。

查找的效率将取决于您的比较器实现。

于 2012-05-13T13:59:54.620 回答
0

如果期间不重叠,那么我建议使用TreeMap<Period, CounterBag>. 当您需要以CounterBag毫秒为单位获得给定时间时,您可以使用以下内容:

// Initialize map
Map<Period, CounterBag> map = new TreeMap<Period, CounterBag>();
map.put(...);

// Prepare "query"
long timeInMillis = ...;
Period fakePeriod = new Period(new Date(timeInMillis), new Date(timeInMillis));

// Get bag for given time.
CounterBag bag = map.get(fakePeriod);

在这种情况下,要么Period必须实现Comparable,要么将自己的比较器传递给树。如果两个时期重叠,则比较它们应该返回 0(在我们的例子中,如果某个真实时期包括我们的假时期,其开始和结束时间等于timeInMillis)。

于 2012-05-13T14:02:49.063 回答
0

因为任何开始时间都可能符合条件,给定足够的持续时间,按开始时间排序的简单 ArrayList 将是一种有效的方法,尤其是在允许重叠的情况下(产生多个结果)。您将仅迭代到开始时间 > 请求 timeInMillis 的第一条记录。

于 2012-05-13T16:31:24.930 回答