2011-11-13 159 views
1

我想知道是否有可能有索引列的多列以加快排序。在MySQL中,您可以在多列上創建索引,這樣可以更快地查找表中的元素,但是我不知道標準java矩陣中是否可能。例如,我的數據是一個3列矩陣,它有一個ID,名字和姓氏,然後在這個表上有很多條目。現在我可以說一些像mat [5]一樣的東西,並獲得個人ID爲5的條目,但我也希望能夠按姓氏列搜索條目。我怎樣才能在Java中最有效地做到這一點?索引一個java矩陣

回答

3

如果是Java,則可以始終設置一個哈希表,該名稱將姓氏與矩陣行索引數組相關聯,以便這些行上的人員具有該姓氏。

或者你可以有一個多級哈希表,這樣你就可以做m[index.get(lastName).get(firstName)]。另外,如果要按字典順序遍歷名稱,可以用TreeMap替換散列表。

例子:

import java.util.*; 
class Test{ 
    public static void main(String[]args){ 

     Object[][] m = new Object[][]{ 
      {1, "Smith", "John"}, 
      {2, "Stone", "Jack"}, 
      {3, "Stein", "Robert"}, 
      {4, "Stone", "Bob"} 
     }; 

     //index.get(lastName) will return a map between 
     //first names and matrix row indices. 
     //index.get(lastName).get(firstName) returns the index 
     //in the matrix of the row pertaining to person (lastName, firstName) 
     TreeMap<String, TreeMap<String, Integer>> index = 
      new TreeMap<String, TreeMap<String, Integer>>(); 

     //create index 
     for(int i=0;i<m.length;i++){ 
      Object[]o = m[i]; 
      String last = o[1].toString(); 
      String first = o[2].toString(); 
      TreeMap<String,Integer> index2 = index.get(last); 
      if (index2==null){ 
       index2=new TreeMap<String,Integer>(); 
       index.put(last, index2); 
      } 
      index2.put(first, i); 
     } 

     System.out.print("Smith, John -> "); 
     System.out.println(Arrays.toString(m[index.get("Smith").get("John")])); 

     System.out.print("Stone -> "); 
     System.out.println(index.get("Stone")); 

     System.out.print("Full index: "); 
     System.out.println(index); 
    } 
} 

輸出:

Smith, John -> [1, Smith, John] 
Stone -> {Bob=3, Jack=1} 
Full index: {Smith={John=0}, Stein={Robert=2}, Stone={Bob=3, Jack=1}} 

在我給的例子,這是不夠的,最後一個名稱映射到排索引,因爲你可以振振有詞地有兩個人有相同的最後名稱。然而,我確實假設你不會有兩個同名的人。否則,你需要類似TreeMap<String, TreeMap<String, ArrayList<Integer>>>的東西,以便能夠找到給定(姓,名)的每個人。 如果您想按ID搜索,您只需創建第二個索引,將ID映射到行索引(可能是HashMap<Integer, Integer>)。

對於這個小例子,索引沒有太大的收穫,因爲它們可能佔用比矩陣本身更多的空間,但是如果您的記錄很大,它可能會帶來回報。

+0

嘿抱歉,我不完全理解你將如何實施你的建議。如果我有一個數組,並且每個槽指向一個散列,並且這些散列中的每個鍵都指向其他散列,那麼如何讓我按姓氏搜索?假設條目是'1 - Smith,John','2 - Stone,Jack','3 - Stein,Robert'。你能告訴我如何使用你的代碼通過它的id(2)和它的姓氏(Stone)來搜索第二個條目嗎? – Kvass

+0

增加了一個例子。 – Vlad

0

一般來說,如果您希望有多種方式來訪問Java數據結構,您將不得不創建額外的「並行」結構。例如,你可以讓你的「主表」 - 無論是數組還是列表或其他 - 按名稱排序或鍵入。然後,您將創建一個按客戶編號排序的第二個表,並且該表中的每個條目都可以將索引保存到第一個表中,或者保存對象句柄的另一個副本。然後,你可以有出生日期,其條目還指出,第一個表格排序的第三個表等

例如:

class Customer 
{ 
    public String name; 
    public int customerNumber; 
    public int shoeSize; 
    ... whatever ... 
} 
class byName implements Comparator<Customer> 
{ 
    public int compareTo(Customer c1, Customer c2) 
    { 
    return c1.name.compareTo(c2.name); 
    } 
} 
class byShoeSize implements Comparator<Customer> 
{ 
    public int compareTo(Customer c1, Customer c2) 
    { 
    return c1.shoeSize-c2.shoeSize; 
    } 
} 

... elsewhere ... 
Customer[] nameOrder=new Customer[100]; 
nameOrder[0]=new Customer("Fred Smith", 10001, 9); 
nameOrder[1]=new Customer("Mary Jones", 10002, 7); 
... etc, however we get the list initialized ... 
Arrays.sort(nameOrder, byName); 

Customer[] shoeSizeOrder=new Customer[100]; 
for (int n=0;n<customerList.length;++n) 
    byNumber[n]=customerList[n]; 
Arrays.sort(shoeSizeOrder, byShoeSize); 

(大多數免責聲明:未經測試的代碼了我的頭頂。等等)錯誤檢查省略和其他過於簡單的說明等等)

在此之後,您將有一個列表按名稱排序,另一個列表按鞋號排序。然後,您可以按順序掃描每個列表,進行二進制搜索以查找特定值,等等。

當然沒有說所有列表必須是數組。它們可以是哈希表,數組列表或任何其他有序或具有鍵/值映射的結構。

請注意,這不是相同數據的兩個副本。只有一組對象。每個對象只有兩個手柄,每個對象一個手柄。