2013-02-07 50 views
0

我很難決定哪個java集合最適合我的場景。目前,我正在閱讀一條記錄,該記錄給了我一個「賬號」和「客戶姓名」的值。要使用哪個java集合?

基於這些值,我需要根據第一個文件給出的帳號和客戶名稱搜索另一個文件。問題是帳號在第二個文件中不唯一,所以我需要使用帳號和客戶名稱進行搜索。

而不是打開,閱讀,搜索,關閉我從第一個文件中讀取的每條記錄的第二個文件,我想將整個文件讀取到一個集合中,並使用集合二進制搜索來查找關聯的記錄第二個文件。

是否有某種類型的集合最適合此目的(如果有的話)?

+3

帳號和客戶是唯一在一起嗎?這樣你可以使用地圖和複雜的關鍵。 – BobTheBuilder

回答

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實例預加載在內存中的第二個文件,而且還AccountIdentifier把你Map

theMap.put(accountIdentifier, customerRecord);

當涉及到搜索的時候,你已經得到了第一個文件的使用accountNumber和客戶名稱,然後執行:

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

最後的評論,如果你的文件是太大,不適合在內存中,那麼你應該考慮使用緩存庫一樣ehcache

1

最好的辦法是創建一個包含帳號和客戶名稱的對象。然後,您可以將您的客戶檔案讀入Map<CustomerInfo, FileInfo>。這裏,CustomerInfo是您的對象,其中只包含客戶名稱和帳號,FileInfo是您的對象,其中包含從文件中讀取的所有信息。現在,您可以對地圖進行簡單的查找。

請注意,您需要確保CustomerInfo實施hashCode()equals()才能正常工作。

1

我認爲這對於如何定義記錄比實際的收藏更有用。

您可以創建一個Comparator來比較兩條記錄,並且基本上考慮了id和名稱,如果這些匹配,則認爲它是相同的記錄。

基於此,您可以使用您定義的比較器來搜索符合條件的記錄的ArrayList(例如)記錄。

二進制搜索是唯一有用的,如果你只返回一個比賽,你可以通過方法簽名看,你需要排序調用二進制搜索Collection之前。

所以,總結:

  • 定義Comparator採用兩個Record對象和檢查,如果他們有相同的ID /名稱。例如,

  • 將所有記錄加載到ArrayList

  • 對它們進行排序。

  • 撥打Collections.binarySearch與您的排序收集和您的自定義比較。

1

爲什麼不做得更快?

創建一類客戶:

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

這樣,你可以搜索幾乎Ø記錄(1)。這種方法還使您能夠搜索accountNumbers(並返回與該號碼關聯的名稱列表)。