我可以使用哪个java集合?

时间:2012-05-13 13:37:47

标签: java collections dictionary map

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

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

感谢您的建议。

5 个答案:

答案 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。