如何有选择地过滤集合中的项目

时间:2010-05-17 05:06:58

标签: java collections

我使用以下代码段来过滤所选用户的列表,其中isSelected是一个布尔变量。是否有更简单的方法(辅助函数)来填充selectedUsers集合,而不是编写以下代码行。

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

5 个答案:

答案 0 :(得分:2)

您可以使用Google Collections中的filter功能;但是,您仍然需要构造谓词对象,如果要操作结果,则必须构造另一个集合并传递结果,因为filter的结果是原始集合的不可变过滤视图。 / p>

使这更具体:

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

当然,这并不是那么干净(除非你为你的谓词创建一个单独的类并碰巧在一堆地方重用它),它实际上返回用户列表,而不是它们的ID ......你必须使用“转换”来获取他们的身份证,所以就个人而言,我会选择你现在所拥有的。

答案 1 :(得分:2)

根据Michael的回答,Apache common的CollectionUtils也有[filter] [1]方法

[1]:http://commons.apache.org/collections/api-2.1.1/org/apache/commons/collections/CollectionUtils.html#filter(java.util.Collection,org.apache.commons.collections.Predicate)

答案 2 :(得分: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类型列表中。

答案 3 :(得分:0)

您可以为它编写自己的代码,这样可以在应用过滤器的每个地方为您节省几行代码(以实用类中的更多代码为代价)。你的电话是否值得......

在一个地方:

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

同样,最后你最终只得到一行代码,代价是其他地方的代码更多。

答案 4 :(得分:0)

您可以使用不同的方法: 如果可能,只需在选择用户时构建selectedUsers列表。 IIRC被称为过度评估 - 这意味着,当选择状态发生变化时,您提供此“计算”,而不是之后。没有上下文,我不能说这对你来说是不是一个好方法。但在某些情况下它很好,因为你不必遍历(可能)长列表。

相关问题