尋找實體集合中所有 ID 的集合
1. 概述
在 Java 中使用領域模型時,我們經常處理從資料庫、API 或記憶體結構中取得的實體集合。幾乎在某個時候,我們都需要從這些實體中提取 ID 清單。這聽起來很簡單,但我們提取 ID 的方式會影響程式碼的可讀性、效能、可維護性以及其他開發人員理解程式碼的難易程度。
在本教程中,我們將探討從實體物件集合中收集 ID 的不同方法。我們將從一個簡單的實體開始,逐步介紹更簡潔的方法。
2. 我們的範例Entity
為了簡單起見,我們將使用一個帶有id字段的基本User實體:
public class User {
private final Long id;
private final String name;
public User(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
}
由於本文重點在於 Java 集合處理,因此未使用 JPA 註解。但是,同樣的方法也適用於 JPA 實體。
3. 經典循環方法
我們大多數人的職業生涯都是從編寫一個簡單的循環來提取ID開始的。它易讀、直觀,並且在所有Java版本中都能運作:
List<Long> extractIdsClassic(List<User> users) {
List<Long> ids = new ArrayList<>();
for (User user : users) {
ids.add(user.getId());
}
return ids;
}
這種方法讓人感覺很熟悉,而且在我們需要最大限度清晰表達時效果很好。但隨著時間的推移,我們逐漸轉向更具表現力和簡潔性的解決方案。
4. 使用 Java Streams
當我們使用 Java 8 及更高版本時,使用流(Stream)通常會使程式碼更簡潔。 Streams讓我們能夠表達我們想要what而不是how獲得它:
List<Long> extractIdsStream(List<User> users) {
return users.stream().map(User::getId).collect(Collectors.toList());
}
這樣比較直觀,也比較容易用眼睛瀏覽。我們能立即明白,我們正在將用戶與其ID進行配對。
5. 使用Set
在許多實際場景中,ID 的設計初衷就是唯一的。但有時我們會處理可能包含重複項的外部資料集。在這種情況下,返回Set可以防止下游出現邏輯錯誤:
Set<Long> extractUniqueIds(List<User> users) {
return users.stream().map(User::getId).collect(Collectors.toSet());
}
這樣就能非常清楚地表達意圖。如果我們的 ID 必須唯一,使用Set就能傳達這個決定。
6. 結論
本文清楚地表明,從實體集合中提取 ID 不僅是一項例行任務,更是一個提升程式碼庫清晰度和一致性的契機。當我們選擇簡潔明了、表達清晰的方法,無論是使用簡單的循環還是現代的 Java Streams ,都能讓我們的意圖更加明確,並降低隱藏 bug 的可能性。
與往常一樣,本文中提供的程式碼可在 GitHub 上找到。