我有一个大型的(超过10万个对象)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
匹配。同样,也可能有其他的组合。
我想知道在这种情况下使用的最佳数据结构/算法是什么。对于精确的搜索,我可以使用hashset或带有自定义比较器的二进制搜索,但我不确定执行这种搜索的最有效方法是什么。
附笔
这不是家庭作业。
我不确定题目是否合适。请随意编辑。
编辑一些你已经指出的事实,我可以使用ssn(例如)的搜索,因为它或多或少是唯一的。上面的exmaple只是对真实场景的说明。实际上,我有几个对象,其中一些字段为空,所以我想搜索其他字段。
3条答案
按热度按时间enxuqcxy1#
基本上,搜索任何属性与查询中的属性匹配的结果。这会将搜索空间缩小到相当小的条目数。从这些结果中,查找符合条件的条目。这意味着您需要遍历并计算有多少属性匹配,如果这超过3,那么您就得到了一个匹配(这个过程相对比较慢,您不希望对整个数据库执行此操作。)
在这种情况下,一种可能的优化方法是从初始筛选阶段删除first\u name和last\u name,因为它们比其他属性(例如,许多人称为“john”的人)更可能得到查询的多个结果。
由于需要匹配三个属性,因此从筛选阶段删除两个属性不会影响最终结果。
9q78igpj2#
只是一个想法;如果你正在寻找一个有ssn的人,你应该能够很快缩小范围,因为只有一个人应该有一个特定的ssn。
3npbholx3#
我不认为有任何特定的数据结构可以使这种匹配/比较更快。
在比较两个对象的简单级别上,可以实现如下方法:
要做大规模的搜索,我能想到的唯一方法是在简单的线性扫描(使用上面的方法)上进行改进
为每个属性创建一系列多重Map,
用用户记录填充它们
然后每次要执行查询时:
查询每个多重Map以获得一组可能的候选对象,
使用迭代所有集合
closeEnough()
找到匹配的。您可以通过将ssn、email address和blog url属性与name属性区别对待来改进这一点。多个用户在前三个属性上匹配应该是很少见的,而不是(比如)找到多个名为“john”的用户。您提出问题的方式需要至少1个ssn、email或url来匹配(以获得3个匹配项),因此您可能根本不需要为名称属性编制索引。