2011-11-13 15 views
1

並べ替えを高速化するために複数の列のインデックスを作成することが可能かどうかを知りたかったのです。 MySQLでは、複数の列にインデックスを付けることができます。これにより、テーブル内の要素をより迅速に見つけることができますが、標準のJavaマトリックスで可能かどうかはわかりません。たとえば、私のデータは、ID、名字、姓、そしてこのテーブルの多くのエントリを持つ3列の行列です。今、私はmat [5]のようなことを言うことができ、5のidを持つ個人のエントリを取得できますが、姓の列でエントリを検索することもできます。どのように私はこれを最も効率的に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}} 

ではありません名。私はしかし、あなたは全く同じ名前の2人の人がいないという前提を立てました。それ以外の場合は、与えられた(姓、名)の人を見つけることができるように、TreeMap<String, TreeMap<String, ArrayList<Integer>>>のようなものが必要です。 IDで検索する場合は、IDを行インデックスにマッピングする2番目のインデックスを作成するだけでよい(HashMap<Integer, Integer>)。この小さな例

は、彼らはおそらくマトリックス自体よりも多くのスペースを取るよう、インデックスを持っていることから得ることがあまりありませんが、あなたのレコードが大きい場合、それはおそらくオフに支払っています。一般的に

+0

ごめんなさいあなたの提案をどのように実装するのか完全に理解していません。配列があり、各スロットがハッシュを指していて、それらのハッシュの各キーが他のハッシュを指している場合、それがどうやって姓で検索できるのでしょうか?エントリは、1 - スミス、ジョン、2 - ストーン、ジャック、3 - スタイン、ロバートです。あなたのコードを使ってid(2)と姓(stone)の両方で2番目のエントリを検索する方法を教えてください。 – Kvass

+0

例を追加しました。 – Vlad

0

あなたはJavaデータ構造にアクセスするための複数の方法をしたい場合は、追加の、「パラレル」構造を作成する必要があるとしています。例えば

、あなたの「メインテーブル」を持つことができます - 名前でソートまたはキーが付いて - それは、配列またはリストまたは何ですか。次に、顧客番号などでソートされた2番目のテーブルを作成し、そのテーブルの各エントリは、最初のテーブルまたはオブジェクトのハンドルの別のコピーにインデックスを保持できます。その後、例えば

そのエントリも最初の表を指す誕生日でソート3番目のテーブル、などを持つことができます:

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); 

(通常免責事項:私の頭の上から未テストコードを。

この後、名前でソートされたリストと靴のサイズでソートされたリストが作成されます。その後、各リストを順番にスキャンしたり、特定の値を見つけるためにバイナリ検索したりできます。

もちろん、すべてのリストは配列でなければならないということはありません。それらは、ハッシュテーブル、配列リスト、または順序付けされた、またはキー/値マッピングを持つその他の構造である可能性があります。

これは同じデータの2つのコピーではありません。オブジェクトのセットは1つだけです。各オブジェクトに2つのハンドルがあり、各リストに1つずつあります。

関連する問題