2017-06-02 43 views
0

我有一個時間戳每個分鐘的統計信息流(每分鐘任意數量的統計信息)。這只是一個持續不斷的統計數據流,不允許在之前改變。此處也沒有併發問題。所以適當的數據結構是map<timestamp,list<stats>>。但是這張圖只需要保留最近30分鐘的數據,所以它也應該排出第一個元素並寫入新的元素(循環緩衝區)。我被告知番石榴HashMultimap是一個很好的候選人使用。但我無法弄清楚如何使用它,找到地圖的第一個和最後一個元素,以及如何刪除最後一個元素。當我看到LinkedHashMultiMap時,我沒有看到找到第一個或最後一個元素的任何方法。我感謝任何幫助。查找在Guava中添加時間的第一個和最後一個元素LinkedHashMultimap/HashMultiMap

+0

我打算髮佈一個答案,但是您可以編輯您的問題以回答以下問題,這些問題將改變您如何實現此目的。 1.是否允許同時訪問Map/Multimap? 2.統計數據列表是否會被修改?還是僅在30分鐘後插入,閱讀並移除? –

+0

在你的問題中,你的鏈接指向LinkedHashMultiset,但文本狀態爲LinkedHashMap。你可能想編輯你的問題來改變文本或鏈接,使它們匹配,這使我昨天感到困惑。我試圖自己編輯它,但我不認爲編輯評論者理解他們不匹配。 –

回答

1

您可以採取幾種方法。我將解釋和展示兩者的例子。我不會解決同步問題,如果有必要,請告訴我,我可以添加詳細信息以確保Multimap代碼是線程安全的。這涉及在訪問其視圖並將其包裝到同步包裝中時在多映射上正確同步。更多細節也可以找到here

  1. 使用Multimap之
  2. 利用番石榴的Cache

對於Multimap之的做法,我會建議你使用LinkedListMultimap。這將確保你的鑰匙是有序和你的價值觀是有序的(因爲你原來說Map<Timestamp, List<Stat>>一種LinkedHashMultimap將保留順序,但它會刪除重複的統計信息。如果這不是一個問題,那麼你可以使用LinkedHashMultimap。

要獲得第一個鍵值,可以使用迭代器或使用Guava的getFirst(Iteratable,defaultValue)實用程序方法。要獲得最後一個鍵值,可以使用Iterables getLast(Iteratable,defaultValue)方法。 如果您的目標只是刪除超過30分鐘的值,您可以忽略Iterables,並使用它們的Multimap鍵的迭代器。

LinkedHashMultimap<Date, Stat> stats = LinkedHashMultimap.create(); 

//Every minute 
stats.putAll(new Date(), newStats); 

//To get the first key inserted into the map 
Date first = Iterables.getFirst(stats.keys(), null); 
//Remove the first entry 
stats.remove(first); 

//To get the last key inserted into the map 
Date last = Iterables.getLast(stats.keys(), null); 
//Remove the last entry 
stats.remove(last); 

//Without using Iterables. 
Set<Date> keys = stats.keys(); 
if (!keys.isEmpty()) { 
    keys.iterator().next().remove(); 
} 

Multimap方法要求您手動管理刪除舊的統計信息。在這方面稍微簡單一些的方法就是使用番石榴的緩存。但是,請注意,這不會保留任何類型的訂單,並且一次獲取值的難度會更大,因爲您沒有插入統計信息的確切時間戳。您需要使用.hashCode().equals(Object)方法創建您自己的自定義Date類,以滿足您的需求。這可能比它值得的更多的工作。

Cache<CustomDate, List<Stat>> cache = CacheBuilder.newBuilder() 
     .expireAfterWrite(30, TimeUnit.MINUTES) 
     .build(); 

cache.put(new CustomDate(), stats); 
List<Stat> statsForTime = cache.get(new CustomDate(/*appropriate initialization*/)); 
+0

非常感謝您的幫助! – Nhome

+0

我很樂意提供幫助。如果此答案或將來的任何其他答案解決了您的問題,則可以將其標記爲表示感謝的方式。 –

相關問題