0

どの Java コレクションが自分のシナリオに最適かを判断するのに苦労しています。現在、「口座番号」と「顧客名」の値を示すレコードを読み込んでいます。

これらの値に基づいて、最初のファイルから得られたアカウント番号と顧客名に基づいて、別のファイルを検索する必要があります。問題は、アカウント番号が 2 番目のファイルで一意ではないため、アカウント番号と顧客名の両方を使用して検索する必要があることです。

最初のファイルから読み取ったすべてのレコードに対して 2 番目のファイルを開き、読み取り、検索し、閉じるのではなく、ファイル全体をコレクションに読み取り、コレクションのバイナリ検索を使用して、2 番目のファイルで関連するレコードを見つけたいと思います。

この目的に最も適した特定のタイプのコレクションはありますか (ある場合)?

4

4 に答える 4

2

あなたが十分なメモリを持っていると仮定すると、私はおそらくを使用しHashMap<AccountIdentifier, CustomerRecord>ます。

CustomerRecord探しているレコードを含むオブジェクトはどこにありますか。

次に、キークラスを作成します。

public class AccountIdentifier {
    public String accountNumber;
    public String customerName;

    public AccountIdentifier(String accountNumber, String customerName) {
        this.accountNumber = accountNumber;
        this.customerName = customerName;
    }
    public int hashCode() {
        return (accountNumber+"#"+customerName).hashCode();
    }

    public boolean equals(Object obj) {
        if(!(obj instanceof AccountIdentifier)) return false;
        else {
            AccountIdentifier id = (AccountIdentifier)obj;
            return accountNumber.equals(id.accountNumber) && customerName.equals(id.customerName);
        }
    }
}

CustomerRecordしたがって、各レコードを読み取り、そこに含まれるデータを使用してインスタンスを作成し、:を挿入して、2番目のファイルをメモリにプリロードする必要がありAccountIdentifierますMap

theMap.put(accountIdentifier, customerRecord);

検索するときが来て、最初のファイルからaccountNumberとcustomerNameを取得したら、次のようにします。

AccountIdentifier accountIdentifier = new AccountIdentifier(accountNumber, customerName);
CustomerRecord record = theMap.get(accountIdentifier);

最後のコメントですが、ファイルが大きすぎてメモリに収まらない場合は、ehcacheなどのキャッシュライブラリの使用を検討する必要があります。

于 2013-02-07T13:21:54.500 に答える
1

最善の策は、口座番号と顧客名の両方を含むオブジェクトを作成することです。次に、顧客ファイルを a に読み込むことができますMap<CustomerInfo, FileInfo>。ここで、CustomerInfoは顧客名と口座番号のみをFileInfo含むオブジェクトであり、 はファイルから読み取ったすべての情報を含むオブジェクトです。これで、マップに対して簡単なルックアップを実行できます。

CustomerInfoこれが適切に機能するためには、その実装hashCode()を確認する必要があることに注意してくださいequals()

于 2013-02-07T13:22:33.763 に答える
1

これは、実際のコレクションよりもレコードを定義する方法に関係があると思います。

2 つのレコードを比較する を作成できます。Comparator基本的に ID と名前が考慮されます。これらが一致する場合は、同じレコードであると見なされます。

これに基づいて、定義したコンパレーターを使用して、ArrayList(たとえば) レコードから基準に一致するレコードを検索できます。

二分検索は、メソッド シグネチャからわかるように、1 つの一致のみを返す場合にのみ役立ちます。また、二分検索を呼び出す前に並べ替える必要がありますCollection

要約すると、次のようになります。

  • Comparator2 つのオブジェクトを取りRecord、それらが同じ ID/名前を持っているかどうかをチェックする a を定義します。

  • たとえば、すべてのレコードを にロードArrayListします。

  • それらを並べ替えます。

  • Collections.binarySearch並べ替えられたコレクションとカスタム コンパレータを使用して呼び出します。

于 2013-02-07T13:23:08.287 に答える
1

なぜそれをもっと速くしないのですか?

クラス Customer を作成します。

 public class Customer {
     private final int accountNumber;
     private final String customerName;

     public Customer (int accountNumber, String customerName) {
          this.accountNumber = accountNumber;
          this.customerName = customerName;
     }
     public boolean equals(Object o) {
          //check if accountNumber and customerName are equal
     } 
     public int hashCode() {
          return 13*accountNumber + 31*customerName.hashCode();
     }
 }
 public class CustomerBucket() {
     private final int forAccountNumber;
     private Map<String, Customer> map = HashMap<String, Customer>();
     public CustomerBucket(int forAccountNumber) {
         //...
     }
     public boolean equals(Object o) {
         return o.forAccountNumber == this.forAccountNumber;
     }
     public int hashCode() {
         return forAccountNumber;
     }
 }
 public class AccountSearcher {
     private final Set<CustomerBucket> set = new HashSet<CustomerBucket>();
     public Customer getCustomer(int accountNumber, String name) {
         return set.get(accountNumber).get(name);
     }
 }

そうすれば、ほぼ O(1) でレコードを検索できます。このアプローチでは、accountNumbers を検索する (そしてその番号に関連付けられた名前のリストを返す) 機能も提供されます。

于 2013-02-07T13:29:25.863 に答える