我需要存储一组数据结构,这些数据结构由一段时间(开始,结束)和此期间的计数器定义,这些结构包含一些复杂的计算结果。数据结构的简化定义如下:
public class CounterBag {
private Period period; // collection key
private Counter counter;
// accessors
// ...
}
Period
就像:
public class Period {
public DateTime start;
public DateTime end;
// accessors
// ...
}
我需要一个包含由CounterBag
定义的Periods
个对象的集合。
该集合需要long timeInMillis
提供有效的查找(这里是catch!),因此HashMap
实际上不是一个选项,因为我不想覆盖equals
和{{1} } hashcode
(我需要他们两个)。集合需要按CounterBag
排序(截止日期)。 Period
具有灵活的持续时间,执行查找的部分不知道。
我想知道java标准API或某些开源库中是否有开箱即用的集合可以帮助我解决它?某种排序集或排序映射可以按日期实现有效的查找。按日期查找将返回Period
,日期为CounterBag
。
感谢您的建议。
答案 0 :(得分:0)
您可以将TreeMap用作Sorted集合(这使查找更有效)
如果您的句点有规律的间隔(这是最简单的形式),您不需要这样的集合。你可以为每个间隔设置一个计数器。例如一个int[]
答案 1 :(得分:0)
我只是扩展@Peter Lawrey的答案,使用TreeMap和CounterBag的自定义比较器。
此比较器将确保返回落在该范围内的CounterBag。
查找效率取决于您的比较器实现。
答案 2 :(得分: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
,或者将自己的比较器传递给树。 2个期间的比较如果重叠则应返回0(在我们的情况下,如果某个实际期间包括我们的假期,其开始和结束时间等于timeInMillis
)。
答案 3 :(得分: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();
答案 4 :(得分:0)
因为可能任何开始时间都有资格,给定足够的持续时间,按开始时间排序的简单ArrayList将是一种有效的方法,特别是如果允许重叠(产生多个结果)。您只会迭代到开始时间&gt;的第一条记录。请求timeInMillis。