我无法确定哪个java集合最适合我的场景。目前,我正在阅读记录,该记录为我提供了“帐号”和“客户名称”值。
根据这些值,我需要根据第一个文件中给出的帐号和客户名称搜索另一个文件。问题是帐号在第二个文件中不是唯一的,因此我需要使用帐号和客户名进行搜索。
我不想打开,阅读,搜索,关闭我从第一个文件中读取的每个记录的第二个文件,而是想将整个文件读入一个集合,并使用集合二进制搜索来查找相关记录。第二档。
是否有某种类型的集合最适合此目的(如果有的话)?
答案 0 :(得分: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
来预先加载内存中的第二个文件。 1}}:
theMap.put(accountIdentifier, customerRecord);
什么时候搜索,你从第一个文件中获得了accountNumber和customerName,然后执行:
AccountIdentifier accountIdentifier = new AccountIdentifier(accountNumber, customerName);
CustomerRecord record = theMap.get(accountIdentifier);
最后评论,如果你的文件太大而无法放入内存,那么你应该考虑使用像ehcache这样的缓存库。
答案 1 :(得分:1)
您最好的办法是创建一个包含帐号和客户名称的对象。然后,您可以将客户文件读入Map<CustomerInfo, FileInfo>
。在这里,CustomerInfo
是您的对象,它只包含客户名称和帐号,FileInfo
是您的对象,其中包含从文件中读取的所有信息。现在,您可以对地图进行简单的查找。
请注意,您需要确保CustomerInfo
实施hashCode()
和equals()
才能使其正常运作。
答案 2 :(得分:1)
我认为这与你如何定义你的记录有关,而不是实际的集合。
你可以创建一个比较两个记录的Comparator
,并且基本上考虑了id和名称,如果这些匹配,你认为它是相同的记录。
基于此,您可以使用您定义的比较器为符合条件的人搜索ArrayList
(例如)记录。
二进制搜索仅在您只返回一个匹配时才有用,正如您可以通过方法签名看到的那样,和需要对{{1>进行排序在调用二进制搜索之前。
所以,总结一下:
定义Collection
,其中包含两个Comparator
个对象,并检查它们是否具有相同的ID /名称。
例如,将所有记录加载到Record
。
对它们进行排序。
使用已排序的集合和自定义比较器调用ArrayList
。
答案 3 :(得分: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的功能(并返回与该数字相关联的名称列表)。