2012-05-13 3 views
3

いくつかの複雑な計算結果を保持するこの期間の期間(開始、終了)とカウンタによって定義される一連のデータ構造を格納する必要があります。次のようなデータ構造の単純化された定義は次のとおりです。私は明確なPeriodsによって定義されたCounterBagオブジェクトを保持しているコレクションを持っている必要がありどのJavaコレクションを使用できますか?

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

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

Periodは同じくらい簡単です。 long timeInMillisによってコレクションが効率的なルックアップを提供する必要があるので、HashMapは実際にはオプションではありません。equalshashcodeを上書きしたくないので(どちらも必要です)。コレクションはPeriod(終了日まで)でソートする必要があります。 Periodは、ルックアップを実行する部分には知られていない柔軟な持続時間です。

Java標準APIまたはいくつかのオープンソースライブラリには、それを解決するのに役立つ既定のコレクションがありますか?ソートされたセットまたは並べ替えられたマップのある種類のもので、日付による効率的なルックアップを実装できます。日付による検索ではCounterBagが返され、日付はPeriodになります。

あなたの提案を気に入ってください。

+2

期間は重複していますか? –

答えて

0

あなたの期間は(最も単純な形式である)、一定の間隔を持っている場合は、このようなコレクションを必要としない(検索が効率的になりた)その分別収集と

をTreeMapのを使用することができます。あなたはちょうど各間隔のためのカウンターを持つことができます。例えばa int[]

+0

ありがとうございます。問題は、 'Period'の開始と終了が柔軟性があり、検索を実行する部分には分からないため、検索は期間ではなく日付で行われるということです。 – aviad

0

私はちょうど@ピーターローリーの答えを拡張するだろう、あなたのCounterBagのカスタムコンパレータでTreeMapを使用してください。

この比較器は、範囲内の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); 

PeriodComparableを実装しなければならないか、ツリーに独自のコンパレータを渡すのいずれか。 2つの期間を比較すると、重複する場合は0が返されます(実際の期間には偽の期間が含まれ、開始時刻と終了時刻はtimeInMillisになります)。

0

私は​​を提案します。潜在的に任意の開始時間は、十分な期間与えられ、開始時刻順にソート簡単なのArrayListを修飾する可能性があるため、複数をもたらす(重複が許可されている場合は特に、効率的なアプローチになり

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

:あなたはNavigableMapインタフェースを使用してアクセスします結果)。開始時間> timeInMillisを要求した場合、最初のレコードまでしか反復しません。

関連する問題