2011-06-05 100 views
8

我有用戶對象列表,我只想根據用戶對象中的變量從列表中獲取用戶對象。從對象列表中獲取基於對象變量的對象

public class User { 

    private int id; 

    private String sex; 

    private int age; 

    private String country; 

    /** 
    * Getter and setter for all variables 
    */ 
} 

我有一個這樣的模型類。現在我有用戶對象列表。

List<User> users = new ArrayList<User>(); 

我想從用戶列表中獲取對象,如果用戶是男性。

List<User> ageList = new ArrayList<User>(); 
for(User object : users) { 
    if(object.getSex().equals("Male")){ 
     ageList.add(object); 
    } 
} 

我不喜歡上面的方法。有沒有更好的方法來從基於對象中的變量的對象列表中獲取對象..?

有什麼函數Java Collections ..?我們可以使用Java比較器來解決這個問題嗎?

回答

7

如果您使用Guava,您可以使用Collections2.filter

Collection<User> males = Collections2.filter(users, new Predicate<User>() { 
    @Override 
    public boolean apply(User user) { 
     return user.getSex().equals("Male"); 
    } 
}); 

而且與Java 8,你可以做得更好:

Collection<User> males = Collections2.filter(users, user -> user.getSex().equals("Male")); 
+1

我不喜歡這種表示法的原因是它更長,並且增加了稍後有人閱讀它的庫/方法可能不熟悉的內容。這是一個恥辱Java沒有更好的支持這個用例(就像幾乎所有其他流行語言:P) – 2011-06-05 10:28:13

+1

@Peter:我同意,Ruby是一個好幾億倍:'males = users.select {| user | user.sex =='男'}' – 2011-06-05 10:30:28

+1

即使無聊和非常古老的SQL'select * from用戶where性別=「男性」''''我傾向於喜歡短而且需要較少符號的表達式。大多數程序員可以理解和編寫簡單的SQL。 – 2011-06-05 10:33:17

3

你可以用lambda函數和反射來做到這一點。但是由於Java不支持閉包,你會發現這種方法更容易出錯,需要更多的代碼並且速度較慢。

如果你想要一個快速的方式來做到這一點,你可以主要是一個地圖<秒,列表<用戶>>或多地圖。

順便說一句:我會使用一個枚舉的人的性別。你應該能夠限制自己的一些可能性;)你可以做類似的國家。

+0

@Arul順便說一句,如果你希望是基於她們的性別屬性來獲取用戶和你改變它是一個枚舉類型,而不是一個字符串,那麼你可以使用一個非常快速的EnumMap,因爲它基於一個數組 – Yaneeve 2011-06-05 10:22:30

+0

有幾種可能性?讓我們來看看......女性,男性,雙性戀,未知和其他(以及我忘記的其他選項)? :-) – 2011-06-05 10:23:00

+0

@Chris,然而,你這樣做,數字會變小。 – 2011-06-05 10:25:38

0

使用MultiValueMapApache common collection或簡單地Map<String List<User>>開始分裂用戶,如果得到用戶根據性別是所有你需要的。

只要你想從一個未分類的集合中獲得特定的用戶,搜索整個集合是必須的。所以沒有更好的方法來檢索它。但是,您可以隱藏表面下的邏輯。

Apache常用集合(和Guava as Chris Jester-Young提到)提供CollectionUtils.select(),您需要做的就是實現Predicate。 (查看Chris Jester-Young的答案以獲得更好的解釋)

或者,不是使用集合來傳遞用戶,而是將其轉化爲UsersUserPack之類的對象。然後,您可以實施方法調用getMaleUsers(),以便爲您返回對象內的所有男性用戶。如果你需要處理特定的對象,這個技巧非常有用。

2

我找到了一種方法java8與流過濾

List<User> males = users.stream().filter(u -> u.getSex().equals("Male")).collect(Collectors.toList());