0

我无法确定哪个 Java 集合最适合我的场景。目前,我正在阅读一条记录,该记录为我提供了“帐号”和“客户名称”值。

基于这些值,我需要根据第一个文件中提供的帐号和客户名称搜索另一个文件。问题是第二个文件中的帐号不是唯一的,所以我需要同时使用帐号和客户名称进行搜索。

我不想为我从第一个文件中读取的每条记录打开、读取、搜索、关闭第二个文件,而是想将整个文件读入一个集合并使用 Collections 二进制搜索来定位第二个文件中的关联记录。

是否有某种类型的收藏最适合这个目的(如果有的话)?

4

4 回答 4

2

假设您有足够的内存,我可能会使用HashMap<AccountIdentifier, CustomerRecord>.

WhereCustomerRecord是一个包含您要查找的记录的对象。

然后创建一个关键类:

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 和 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

我认为这更多地取决于您如何定义您的记录,而不是实际收藏。

您可以创建一个Comparator比较两条记录的记录,并且基本上考虑了 id 和 name,如果它们匹配,则假设它是相同的记录。

基于此,您可以使用您定义的比较器来搜索ArrayList(例如)符合您条件的记录。

二进制搜索仅在您仅返回一个匹配项时才有用,正如您从方法签名中看到的那样,并且您需要Collection在调用二进制搜索之前对其进行排序。

所以,总结一下:

  • 定义一个Comparator接受两个Record对象并检查它们是否具有相同 id/name 的 a。

  • 例如,将所有记录加载到一个ArrayList中。

  • 对它们进行排序。

  • Collections.binarySearch使用您的排序集合和自定义比较器调用。

于 2013-02-07T13:23:08.287 回答
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);
     }
 }

这样,您几乎可以在 O(1) 中搜索记录。此方法还使您能够搜索 accountNumbers(并返回与该号码关联的名称列表)。

于 2013-02-07T13:29:25.863 回答