我很難決定哪個java集合最適合我的場景。目前,我正在閱讀一條記錄,該記錄給了我一個「賬號」和「客戶姓名」的值。要使用哪個java集合?
基於這些值,我需要根據第一個文件給出的帳號和客戶名稱搜索另一個文件。問題是帳號在第二個文件中不唯一,所以我需要使用帳號和客戶名稱進行搜索。
而不是打開,閱讀,搜索,關閉我從第一個文件中讀取的每條記錄的第二個文件,我想將整個文件讀取到一個集合中,並使用集合二進制搜索來查找關聯的記錄第二個文件。
是否有某種類型的集合最適合此目的(如果有的話)?
我很難決定哪個java集合最適合我的場景。目前,我正在閱讀一條記錄,該記錄給了我一個「賬號」和「客戶姓名」的值。要使用哪個java集合?
基於這些值,我需要根據第一個文件給出的帳號和客戶名稱搜索另一個文件。問題是帳號在第二個文件中不唯一,所以我需要使用帳號和客戶名稱進行搜索。
而不是打開,閱讀,搜索,關閉我從第一個文件中讀取的每條記錄的第二個文件,我想將整個文件讀取到一個集合中,並使用集合二進制搜索來查找關聯的記錄第二個文件。
是否有某種類型的集合最適合此目的(如果有的話)?
假設你有足夠的內存,我可能會使用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。
最好的辦法是創建一個包含帳號和客戶名稱的對象。然後,您可以將您的客戶檔案讀入Map<CustomerInfo, FileInfo>
。這裏,CustomerInfo
是您的對象,其中只包含客戶名稱和帳號,FileInfo
是您的對象,其中包含從文件中讀取的所有信息。現在,您可以對地圖進行簡單的查找。
請注意,您需要確保CustomerInfo
實施hashCode()
和equals()
才能正常工作。
我認爲這對於如何定義記錄比實際的收藏更有用。
您可以創建一個Comparator
來比較兩條記錄,並且基本上考慮了id和名稱,如果這些匹配,則認爲它是相同的記錄。
基於此,您可以使用您定義的比較器來搜索符合條件的記錄的ArrayList
(例如)記錄。
二進制搜索是唯一有用的,如果你只返回一個比賽,你可以通過方法簽名看,和你需要排序調用二進制搜索Collection
之前。
所以,總結:
定義Comparator
採用兩個Record
對象和檢查,如果他們有相同的ID /名稱。例如,
將所有記錄加載到ArrayList
。
對它們進行排序。
撥打Collections.binarySearch
與您的排序收集和您的自定義比較。
爲什麼不做得更快?
創建一類客戶:
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(並返回與該號碼關聯的名稱列表)。
帳號和客戶是唯一在一起嗎?這樣你可以使用地圖和複雜的關鍵。 – BobTheBuilder