2011-09-20 88 views
25

我有一個數據庫收到的DTO列表,他們有一個ID。我想確保我的列表包含具有指定ID的對象。顯然,在這種情況下創建一個帶有預期字段的對象將無濟於事,因爲contains()調用Object.equals(),並且它們不會相等。查找對象列表是否包含具有指定字段值的內容?

我想出了這樣一個解決方案:創建了一個接口HasId,在我所有的DTO中實現了它,並且繼承了一個帶有contains(Long id)方法的新類的ArrayList。

public interface HasId { 
    void setId(Long id); 
    Long getId(); 
} 

public class SearchableList<T extends HasId> extends ArrayList<T> { 
    public boolean contains(Long id) { 
     for (T o : this) { 
      if (o.getId() == id) 
       return true; 
     } 
     return false; 
    } 
} 

但在這種情況下,我不能強制轉換列表和ArrayList到SearchableList ... 我忍受這一點,但希望確保我沒有發明了自行車。

EDIT(十月'16):

當然,引進的lambda表達式在Java中8到這樣做的方法很簡單:

list.stream().anyMatch(dto -> dto.getId() == id); 
+9

我相信你的意思是'發明輪子'。 – Nishan

+0

爲什麼不只是搜索列表? –

+0

尼山,這正是我的意思,這是一個翻譯問題:D Ray Tayek,哇,這樣一個簡單而優雅的想法甚至沒有跨過我的腦海,我會確保我會嘗試一下,謝謝 – Sergey

回答

44

我建議建立像你這樣簡單的靜態方法寫道,沒有任何額外的接口:

public static boolean containsId(List<DTO> list, long id) { 
    for (DTO object : list) { 
     if (object.getId() == id) { 
      return true; 
     } 
    } 
    return false; 
} 
+0

爲了更好的代碼可讀性,我會刪除for和if的括號。我認爲這是很好的做法。無論如何感謝這種方法! – wzieba

+0

嗯,不是性能方面的最佳選擇,我認爲@ medopal的解決方案更好 – Choletski

+1

@Choletski這裏的表現有什麼問題?假設我們不使用並行計算,你不可能比O(N)做得更好。 –

2

嗯,我認爲你的方法是有點太過複雜的問題。 你說:

我有一個從數據庫收到的DTO列表,他們有一個ID。

那麼可能你應該使用DTO類來保存這些項目。如果是這樣,把id getter和setter放在該類中:

public class DTO implements HasId{ 
    void setId(Long id); 
    Long getId(); 
} 

這就足夠迭代和ArrayList並搜索所需的id。 擴展ArrayList類僅用於添加「compare-id」feautre似乎過於複雜。 @Nikita Beloglazov就是一個很好的例子。你可以概括它甚至更多:

public boolean containsId(List<HasId> list, long id) { 
    for (HasId object : list) { 
     if (object.getId() == id) { 
      return true; 
     } 
    } 
    return false; 
} 
8

我建議你只是覆蓋在你的SearchableDto它會是這樣的equals

public boolean equals(Object o){ 
    if (o instanceof SearchableDto){ 
     SearchableDto temp = (SearchableDto)o; 
     if (this.id.equals(temp.getId())) 
      return true; 
    } 
    return false; 
} 

在這種情況下contains或許應該工作,如果它具有相同的id ;

0

您的要求不清楚。當你說「保證我的列表中包含有指定ID的對象」你想:

  1. 檢測如果ID存在並與你的結果所需的ID相應的行動
  2. 總是包含DTO

大多數回覆都假設你的意思是1,但是當你考慮這個問題的時候,你可以在問題的措詞上給出2。你可以通過改變你的查詢包括所需的結果:

SELECT * FROM employee WHERE firstname = 'John' OR id = 42; 
+0

這是一個測試語句,我想確保我的Hibernate代碼正確地執行了它的映射並從數據庫中提取了正確的值。 – Sergey

+0

那麼,如果這是一個特定的測試用例,那麼爲什麼不循環遍歷檢索到的對象,並且如果找不到所需的ID,則測試失敗?爲什麼你要把所有的DTO實現爲HasId接口? –

0
public boolean containsId(List<HasId> list, long id) { 
    boolean flag = false; 
    for (HasId object : list) { 
     if (object.getId() == id) { 
      flag = true; 
     } 
    } 
    return flag; 
} 
+0

更好地打破'每個'循環一旦標誌值爲true,而不是循環直到結束 –

0

這是我在DFS GetUnvisitedNeighbour功能使用。

public static int GetUnvisitedNeighbour(int v) 
{ 
    Vertex vertex = VertexList.stream().filter(c -> c.Data == v).findFirst().get(); 
    int position = VertexList.indexOf(vertex); 
    ... 
} 

我曾經在C#中工作。 C#中的Lambda表達式比在Java中處理起來要容易得多。

您可以使用filter函數爲元素的屬性添加條件。

然後根據您的邏輯使用findFirst().get()findAny.get()

相關問題