2009-11-02 15 views
1

我有一個很大(超過100K對象)的Java對象集合,如下所示。如何在Java bean中執行不精確的比較?

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="[email protected]", 
blog_url="http://myblog.wordpress.com" 

搜索應該返回我的所有對象,其中first_name,last_name and ssn匹配或那些last_name, ssn, email and blog_url比賽。同樣,也可以有其他組合。

我想知道什麼是最好的數據結構/算法在這種情況下使用。對於精確搜索,我可以使用自定義比較器的哈希集或二進制搜索,但我不確定執行此類搜索的最有效方法是什麼。

P.S.

  • 這是不是一個課外練習。

  • 我不確定問題標題是否合適。請隨意編輯。

編輯 你們中有些人指出這樣的事實,我可以用SSN(爲前)的搜索,因爲它或多或少是唯一的。上面的例子只是說明真實情況。實際上,我有幾個對象,其中一些字段爲空,所以我想在其他字段上搜索。

回答

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

要進行大規模的搜索,我能想到的唯一的辦法就是提高一個簡單的線性掃描(使用上述方法)將是

  1. 創建一系列屈德寧爲每個屬性的,
  2. 與用戶記錄填充它們

然後你想要做一個查詢中的每個時間:

  • 查詢每個多重映射來獲得一組可能的候選人,
  • 迭代所有使用closeEnough()套的發現比賽。
  • 您可以通過將SSN,電子郵件地址和博客URL屬性與名稱屬性區別對待來改善此問題。與(比方說)找到稱爲「John」的多個用戶相比,前三個屬性中匹配的多個用戶應該很少出現。您提出問題的方式至少需要1個SSN,電子郵件或URL匹配(以獲得3個匹配項),所以也許您根本無法打擾索引名稱屬性。

    1

    基本上,搜索任何屬性與查詢中的屬性相匹配的結果。這應該將搜索空間縮小到相當少量的條目。從這些結果中,查找符合條件的條目。這意味着你需要檢查並計算有多少屬性匹配,如果超過3則表示匹配。 (這個過程相對較慢,您不想在整個數據庫中執行此操作。)

    在這種情況下,潛在的優化是從初始過濾階段刪除first_name和last_name,因爲它們更多可能會讓你獲得多個查詢結果而不是其他屬性(例如很多人稱爲「John」)。

    由於三個屬性需要匹配,從過濾器階段移除兩個不會影響最終結果。

    0

    只是一個想法;如果你正在尋找一個有SSN的人,那麼你應該能夠很快地縮小它,因爲只有一個人應該有一個特定的SSN。

    +0

    電子郵件和blog_url也不太可能在幾個人之間共享。 – Artelius 2009-11-02 22:18:51

    +0

    @ moowiz2020和@Artelius,好點。但這只是說明問題的一個例子。實際上,我所搜索的項目並非如此獨特或始終可用(例如,對於某些用戶,ssn爲空)。也許我應該選擇一個更好的例子。 – Rahul 2009-11-03 01:35:26