2012-05-13 32 views
3

我需要存儲一段由一段時間(開始,結束)和計數器定義的數據結構,該時間段包含一些複雜的計算結果。的數據結構的簡化的定義如下:我可以使用哪個java集合?

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

Period很簡單,只要:

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

我需要有保持由不同Periods定義CounterBag對象的集合。 收集需要提供有效的查找(這裏是趕上!)通過long timeInMillis,所以HashMap是不是一個真正的選擇,因爲我不希望覆蓋equalsCounterBaghashcode(我需要他們兩人)。收集需要按Period排序(截止日期)。 Period具有靈活的持續時間,對於執行查找的部分是不知道的。

我想知道java標準API或某些開源庫中是否有可以幫助我解決問題的開箱即用的集合?某種有序的集合或有序映射,可以按日期實現高效查找。按日期查找將返回CounterBagPeriod日期落入。

感謝您的建議。

+2

週期是否重疊? –

回答

0

你可以使用TreeMap中作爲一個分類收集(這使得查找效率)

如果你的月經有規律的間隔(這是最簡單的形式),你不需要這樣一個集合。您可以爲每個間隔設置一個計數器。例如a int[]

+0

謝謝,問題是'Period'的開始和結束是靈活的,並且不會被執行查找的部分所知,所以查找將按日期而不是按週期完成。 – aviad

0

我只會擴展@Peter Lawrey的答案,使用TreeMap和CounterBag的自定義比較器。

該比較器將確保落在該範圍內的CounterBag被返回。

查找的效率將取決於您的比較器實現。

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或者你通過自己的比較樹。如果兩個期間重疊(如果某個實際期間包括我們的假期,開始和結束時間等於timeInMillis),則兩個期間的比較應該返回0。

0

我建議一個​​。您會使用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(); 
0

因爲潛在的任何開始時刻可能有資格,給定足夠的持續時間,由開始時間排序的簡單的ArrayList將是一種有效的方法,尤其是如果允許交迭(產生多個結果)。您只需迭代到開始時間>請求timeInMillis的第一條記錄。

相關問題