2012-04-28 73 views
1

這是一個棘手的數據結構和數據組織案例。Java地圖內容比較

我具有從大的文件中讀取數據,併產生多種類型(例如,BooleanIntegerString),其被歸類於幾個(小於十幾)基團,然後存儲在數據庫中的對象的應用程序。

每個對象當前存儲在一個單一的HashMap<String, Object>數據結構中。每個這樣的HashMap對應於單個類別(組)。每個數據庫記錄都是根據所有類別(HashMap數據結構)中包含的所有對象中的信息構建的。

要求檢查後續記錄是否與列的數量和類型「等效」,必須通過比較每個地圖的名稱(HashMap鍵)和每個類型(實際類別)存儲的對象。

我正在尋找一種有效的方式來實現此功能,同時保持原始對象的分類,因爲以最快的方式按類別列出對象也是一項要求。

一個想法是對鍵進行排序(例如,將HashMap替換爲TreeMap),然後遍歷所有地圖。另一種方法是僅複製TreeMap中的所有內容,僅用於比較目的。

什麼是實現此功能的最有效方式?

另外,如果您將如何去查找連續記錄之間的差異(即添加的字段和刪除的字段)?

回答

2

創建一個元分類集,在其中存儲所有創建的地圖。

裝置SortedSet<Map<String,Object>>例如一個TreeSet作爲一個自定義Comparator<Map<String,Object>>它確實檢查您的要求相同的數字和鍵的名稱和每個值相同的對象類型。

然後,您可以使用此元集結構的contains()方法來查明是否已經存在類似的記錄。

==== ====編輯

自從我misundertood擺在首位數據庫記錄和地圖之間的關係,現在我已經改變了一些語義我的答案當然一點點。

我仍然會使用上述SortedSet<Map<String,Object>>,但當然Map<String,Object>現在會指向您和havexy建議的Map。

在另一方面也可能是前進了一步使用Set<Set<KeyAndType>>SortedSet<Set<KeyAndType>>在您KeyAndType將僅包含鍵,用適當的Comparable實現或equals with hashcode類型。

爲什麼?你問如何找到兩個記錄之間的差異?如果每條記錄都與其中一個內部相關Set<KeyAndType>,則可以使用retainAll()輕鬆地形成兩個連續集合的交集。

如果您想將此與SortedSet<Map<String,Object>>的想法進行比較,您可以用兩種方法比較比較器中的字段之間的差異,一次比較內部集合,一次比較內部映射。而且由於這些信息在構建周圍集合時會丟失,因此如果您沒有其他易於使用的簡化結構來查找這些差異,那麼以後很難獲得兩條記錄之間的差異。既然這樣一個Set<KeyAndType>可以作爲兩個記錄之間比較的關鍵以及簡單的基礎,它可能是一個很好的候選人用於兩個目的。

如果您還想要保留之間的關係這樣的Set<KeyAndType>您記錄或組Map<String,Object>你的元結構的可能是這樣的: Map<Set<KeyAndType>,DatabaseRecord>Map<Set<KeyAndType>,GroupOfMaps>通過簡單LinkedHashMap允許在原來的順序簡單的迭代實現。

+0

所以你的意思是我應該創建一個實現比較器>的自定義TreeSet?這將對Map 對象進行「排序」,但它如何對其內容進行排序? – PNS 2012-04-28 23:56:53

+0

@PNS在第二次閱讀你的描述後,我再也不確定了,如果我理解正確的話。你從文件中讀取String,Boolean,Integer等類型。稍後您將討論關於記錄組合的列。原始人沒有這樣的,所以我假設一個記錄將轉化爲你談話的那些地圖之一,因爲keys = columns。但是,也許你可以首先評論一下以澄清它? – Omnaest 2012-04-29 08:48:06

+0

你幾乎是正確的。記錄是所有地圖的聯合,鍵是列名。 – PNS 2012-04-29 21:58:49

2

一個解決方案是保持基於類別HashMap和組合TreeMap。這將有稍微更多的內存要求,但不是太多,因爲你會保持在他們兩個相同的參考。

因此,無論何時添加/刪除至HashMap,您也將在TreeMap中執行相同的操作。這兩種方式將始終保持同步。

然後,您可以使用TreeMap進行比較,無論您是想比較對象類型還是實際內容比較。