2010-07-25 22 views
0

我有一個二維數組我該如何在java表上執行類似SQL的查找?

public static class Status{ 
public static String[][] Data= { 
{ "FriendlyName","Value","Units","Serial","Min","Max","Mode","TestID","notes" }, 
{ "PIDs supported [01 – 20]:",null,"Binary","0",null,null,"1","0",null }, 
{ "Online Monitors since DTCs cleared:",null,"Binary","1",null,null,"1","1",null }, 
{ "Freeze DTC:",null,"NONE IN MODE 1","2",null,null,"1","2",null }, 

我想

SELECT "FriendlyName","Value" FROM Data WHERE "Mode" = "1" and "TestID" = "2" 

我該怎麼辦呢?最快的執行時間非常重要,因爲每分鐘可能有數百個這樣的時間。

+1

是否有你不能真正使用數據庫的原因? HSQLDB和Derby都非常快速和輕便。 – mlschechter 2010-07-25 02:19:52

回答

0

我最終使用了一個查找表。 90%的數據是從頂部附近引用的。

public static int lookupReferenceInTable (String instanceMode, String instanceTID){ 
     int ModeMatches[]=getReferencesToMode(Integer.parseInt(instanceMode)); 
     int lineLookup = getReferenceFromPossibleMatches(ModeMatches, instanceTID); 
     return lineLookup; 
    } 



     private static int getReferenceFromPossibleMatches(int[] ModeMatches, String instanceTID) { 
     int counter = 0; 
     int match = 0; 
     instanceTID=instanceTID.trim(); 
     while (counter < ModeMatches.length){ 
     int x = ModeMatches[counter]; 
     if (Data[x][DataTestID].equals(instanceTID)){ 
     return ModeMatches[counter]; 
     } 
     counter ++ ; 
     } 
     return match; 

    } 

它可以被進一步優化,這樣,而不是通過所有陣列就會對列循環的循環,直到它找到一個匹配,則循環的下一個,那麼下一個。數據以流暢有序的方式進行佈局,因此,基於3條標準的查找應僅執行與行相等的多個檢查。

1

想想它應該有多普遍。真正像SQL這樣通用的解決方案可能看起來不像某些特定查詢的解決方案。當你提出它時,我傾向於避免二維數組的字符串,而是創建一個集合 - 可能是一個ArrayList,但如果你正在頻繁插入&刪除,也許一個LinkedList會更合適 - - 一些結構類的類。所以

List<MyThing> list = new ArrayList<MyThing>(); 

和索引要在其上使用一個HashMap搜索字段:

Map<Integer, MyThing> modeIndex = new HashMap<Integer, MyThing>() 
for (MyThing thing : list) 
    modeIndex.put(thing.mode, thing); 

把它寫下來讓我意識到自己不會做,在其本身,因爲多事情可能有相同的模式。所以可能是一個multimap - 或者通過將地圖的值類型設置爲MyThing而不是MyThing來實現,而是List。 Google Collections有一個很好的multimap實現。

0

這並不完全回答您的問題,但可以將其中的某些Java RDBM完全運行在您的JVM內存中。例如,HSQLDB。這將爲您提供SQL選擇的全部功能,而無需光盤訪問的開銷。唯一的問題是你不能像查詢的那樣查詢原始的Java數據結構。您首先必須將數據插入數據庫的內存表中。

(我還沒有嘗試這個......或許,如果這種做法是可行的真有人可以發表評論。)

0

至於你的實際問題,在C#中他們曾經使用LINQ(語言集成查詢)爲此,這受益於語言對closures的支持。目前Java 6是最新的官方版本,但Java不支持閉包,但即將推出的Java 7中將支持come。基於Java 7的LINQ的等價物很可能是JaQue

對於您的實際問題,您肯定是在使用錯誤的數據結構作業。您最好的選擇是將String[][]轉換爲List<Entity>,並使用Carl Manaster建議的方便搜索/過濾API的GuavaIterables#filter()將是一個好的開始。

0

編輯:我看看你的數組,我認爲這絕對是一個RDBMS的工作。如果您希望內存數據結構像功能(快速/不需要數據庫服務器),嵌入式內存數據庫(如HSQLDB),H2可以提供這些功能。

如果你想要很好的執行時間,你必須有一個好的數據結構。如果您只是將數據存儲在二維數組中,那麼您將主要使用O(n)。

你需要的是索引,就像其他RDBMS一樣。例如,如果你用了很多的WHERE條款這樣WHERE name='Brian' AND last_name='Smith',你可以做這樣的事情(一種僞碼的):

Set<Entry> everyEntry = //the set that contains all data 
Map<String, Set<Entry>> indexedSet = newMap(); 
for(String name : unionSetOfNames){ 
    Set<Entry> subset = Iterables.collect(new HasName(name), everyEntries); 
    indexedSet.put(name, subset); 
} 
//and later... 
Set<Entry> brians = indexedSet.get("Brian"); 
Entry target = Iterables.find(new HasLastName("Smith"),brians); 

(請原諒我,如果番石榴API的用法是錯誤的示例代碼(它是僞代碼!但你明白了)

在上面的代碼中,你將一次查詢O(1),然後再查找另一個O(n)查找,但是在很多因此這比在整個集合上進行O(n)查找等更有效。如果使用按last_name排序並使用二分搜索的有序集合,則該查找將變爲O(log n)。事情就是這樣,那裏有大量的數據結構這只是一個非常簡單的例子。所以最後,如果我是你,我將定義自己的類並使用JDK中提供的一些標準數據結構創建數據結構。如果這還不夠,我可能會看到其他一些數據結構,但如果它變得非常複雜,我想我只會使用一些內存中的RDBMS,如HSQLDB或H2。它們很容易嵌入,所以與擁有自己的內存數據結構相當接近。隨着越來越多的人做複雜的事情,這個選擇可能會提供更好的性能。

另請注意,我在示例代碼中使用了Google Guava庫。它們非常好,我強烈建議使用它們,因爲它非常好。當然,不要忘了查看java.utli.collections包。

相關問題