2010-05-17 68 views
4

我使用以下代碼片段篩選選定用戶的列表,其中isSelected是布爾變量。有一種更簡單的方法(幫助函數)來填充selectedUsers集合,而不是寫下面的代碼行。如何選擇性篩選集合中的項目

List<User> selectedUsers = new ArrayList<User>(0); 
for (User user : this.getUsers()) { 
    if (user.isSelected()) { 
     selectedUsers.add(user.getId()); 
    } 
} 
+2

你在這裏得到的代碼與在Java中選擇一個新的集合時一樣好。即使你使用Google Collections這樣的東西,你也會得到更多的代碼。 – msandiford 2010-05-17 05:20:40

+0

代碼很好,但arrayConstructor(initialCapacity)的0參數可能無用,可能會令人困惑(有些人會混淆容量和大小)。使用空構造函數更簡單和乾淨。 – leonbloy 2010-05-17 11:37:01

+0

您的列表'selectedUsers'包含'User'實例,所以除非您的'user.getId()'方法返回一個用戶(不太可能)''selectedUsers.add(user.getId())'不會編譯。改爲嘗試'selectedUsers.add(user)'。 – 2011-03-27 12:32:19

回答

2

您可以使用Google Collections的filter函數;但是,仍然需要構造一個謂詞對象,並且如果要操縱結果,則必須構造另一個集合並將結果傳入,因爲過濾器的結果是原始集合的不可變過濾視圖。

爲了使這更加具體:

List<User> selectedUsers = new ArrayList<User>(
      Iterables.filter(
        this.getUsers(), 
        new Predicate<User>() 
         { 
          public boolean apply(User usr){ 
           return usr.isSelected(); 
          } 
         } 
      )); 

當然,這是不是真的那麼幹淨多了(除非你犯了一個單獨的類爲您的謂語發生重用一堆的地方),和它實際上會返回用戶列表,而不是他們的ID ......您將不得不使用「變換」來獲得他們的ID,因此,我個人而言,我只會按照您現在的方式去做。

+0

我現在沒有對google-collections的依賴,是否有任何來自java收藏或Apache公共實用程序 – Sam 2010-05-17 05:13:07

+0

@Samuel的,不是我所知道的。 – 2010-05-17 05:17:22

+1

謝謝,這些迴應絕對有助於澄清我的疑問。看起來沒有簡單的代碼片段,比我提供的代碼片段更簡單。 – Sam 2010-05-17 05:34:35

0

濾波另一種做法是維護選定用戶的列表。 在setSelected(true)中,您可以將用戶添加到列表中,並使用setSelected(false)將其刪除。

class User { 
    List<User> selectedUsers = new ArrayList<User>(0); 

    void setSelected(boolean isSelected) { 
     if (isSelected) { 
      selectedUsers.add(user.getId()); 
     } 
     else { 
      int idx = selectedUsers.indexOf(this); 
      if (idx >= 0) 
       selectedUsers.remove(idx); 
     } 
    } 
} 

這個問題需要實現一個equals方法。順便說一句,你的代碼片段將userId(Int?)添加到User類型的列表中。

+0

所選位在最終用戶的用戶界面中設置 – Sam 2010-05-17 05:32:11

0

您可以爲它編寫自己的代碼,這將爲您在應用過濾器的每個位置(以util類中更多代碼爲代價)節省幾行代碼。您的電話是否值得或不...

在一個地方:

public interface Filter<T> { 
    boolean select(T t); 
    } 

    public static <E> List<E> select(Collection<? extends E> es, Filter<? super E> filter) { 
    final List<E> result = new ArrayList<E>(); 
    for (E e : es) { 
     if (filter.select(e)) { 
     result.add(e); 
     } 
    } 
    return result; 
    } 

和謂詞:

private static class Filter<User> selectedUserFilter = new Filter<User>() { 
    public boolean select(User user) { 
     return user.isSelected(); 
    } 
    }; 

Aaaand:

final List<User> selectedUsers = Util.select(this.getUsers(), selectedUserFilter); 

同樣,你結束最後只有一行代碼,代價是其他地方的代碼更多。

0

您可以使用不同的方法: 如果可能,只需在選擇用戶時建立您的selectedUsers列表。 IIRC通過急切的評估來調用 - 這意味着,當選擇狀態發生變化時,您提供此「計算」,而不是之後。沒有語境,我不能說它是否適合你。但在某些情況下,這很好,因爲您不必遍歷(可能)長列表。