我有一个大的(超过100K对象)Java对象集合,如下所示。
public class User
{
//declared as public in this example for brevity...
public String first_name;
public String last_name;
public String ssn;
public String email;
public String blog_url;
...
}
现在,我需要在此列表中搜索至少3个(任意3个或更多)属性与被搜索对象的属性匹配的对象。
例如,如果我正在搜索具有
的对象 first_name="John",
last_name="Gault",
ssn="000-00-0000",
email="xyz@abc.com",
blog_url="http://myblog.wordpress.com"
搜索应该返回first_name,last_name and ssn
匹配的所有对象或last_name, ssn, email and blog_url
匹配的对象。同样,可能还有其他组合。
我想知道在这种情况下使用的最佳数据结构/算法是什么。对于精确搜索,我可以使用自定义比较器的哈希集或二进制搜索,但我不确定执行此类搜索的最有效方法是什么。
P.S。
这是不的家庭作业。
我不确定问题标题是否合适。请随时编辑。
修改 你们中的一些人已经指出我可以使用ssn(例如)进行搜索,因为它或多或少是唯一的。上面的例子仅说明了真实场景。实际上,我有几个对象,其中一些字段为空,所以我想搜索其他字段。
答案 0 :(得分:2)
我认为没有任何特定的数据结构可以快速进行这种匹配/比较。
在比较两个对象的简单级别,您可以实现这样的方法:
public boolean closeEnough(User other) {
int count = 0;
count += firstName.equals(other.firstName) ? 1 : 0;
count += lastName.equals(other.lastName) ? 1 : 0;
count += ssn.equals(other.ssn) ? 1 : 0;
count += email.equals(other.email) ? 1 : 0;
...
return count >= 3;
}
要进行大规模搜索,我能想到的唯一方法是在简单的线性扫描(使用上述方法)上改进
然后每次你想要进行查询:
closeEnough()
迭代所有集合以查找匹配项。您可以通过将SSN,电子邮件地址和博客URL属性与名称属性区别对待来改进此问题。与(例如)查找名为“John”的多个用户相比,前三个属性上具有匹配项的多个用户应该是罕见的。您提出问题的方式需要至少一个SSN,电子邮件或URL匹配(以获得3个匹配项),因此您可能根本无法为名称属性编制索引。
答案 1 :(得分:1)
基本上,搜索任何属性与查询中的属性匹配的结果。这应该将搜索空间缩小到相当少的条目。从这些结果中,查找符合条件的条目。这意味着你需要经历并计算有多少属性匹配,如果这超过3,那么你就得到了一个匹配。 (此过程相对较慢,您不希望在整个数据库中执行此操作。)
在这种情况下,潜在的优化是从初始过滤阶段中删除first_name和last_name,因为它们比其他属性更有可能为查询获取多个结果(例如,很多人称为“John” “)。
由于三个属性需要匹配,因此从过滤阶段中删除两个属性不会影响最终结果。
答案 2 :(得分:0)
只是一个想法;如果你正在寻找有SSN的人,你应该能够迅速缩小它,因为只有一个人应该有一个特定的SSN。