如何在JavaBeans中执行不精确比较?

jjhzyzn0  于 2021-07-05  发布在  Java
关注(0)|答案(3)|浏览(322)

我有一个大型的(超过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只是对真实场景的说明。实际上,我有几个对象,其中一些字段为空,所以我想搜索其他字段。

enxuqcxy

enxuqcxy1#

基本上,搜索任何属性与查询中的属性匹配的结果。这会将搜索空间缩小到相当小的条目数。从这些结果中,查找符合条件的条目。这意味着您需要遍历并计算有多少属性匹配,如果这超过3,那么您就得到了一个匹配(这个过程相对比较慢,您不希望对整个数据库执行此操作。)
在这种情况下,一种可能的优化方法是从初始筛选阶段删除first\u name和last\u name,因为它们比其他属性(例如,许多人称为“john”的人)更可能得到查询的多个结果。
由于需要匹配三个属性,因此从筛选阶段删除两个属性不会影响最终结果。

9q78igpj

9q78igpj2#

只是一个想法;如果你正在寻找一个有ssn的人,你应该能够很快缩小范围,因为只有一个人应该有一个特定的ssn。

3npbholx

3npbholx3#

我不认为有任何特定的数据结构可以使这种匹配/比较更快。
在比较两个对象的简单级别上,可以实现如下方法:

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;
}

要做大规模的搜索,我能想到的唯一方法是在简单的线性扫描(使用上面的方法)上进行改进
为每个属性创建一系列多重Map,
用用户记录填充它们
然后每次要执行查询时:
查询每个多重Map以获得一组可能的候选对象,
使用迭代所有集合 closeEnough() 找到匹配的。
您可以通过将ssn、email address和blog url属性与name属性区别对待来改进这一点。多个用户在前三个属性上匹配应该是很少见的,而不是(比如)找到多个名为“john”的用户。您提出问题的方式需要至少1个ssn、email或url来匹配(以获得3个匹配项),因此您可能根本不需要为名称属性编制索引。

相关问题