как выборочно фильтровать элементы в коллекции - PullRequest
4 голосов
/ 17 мая 2010

Я использую следующий фрагмент для фильтрации списка выбранных пользователей, где isSelected - логическая переменная. Существует ли более простой способ (вспомогательная функция) для заполнения коллекции selectedUsers вместо написания следующих строк кода.

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

Ответы [ 5 ]

2 голосов
/ 17 мая 2010

После ответа Майкла, CollectionUtils Apache common также имеет методы [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 голосов
/ 17 мая 2010

Вы можете использовать функцию filter из Google Collections; однако вам все равно нужно будет создать объект предиката, и если вы хотите манипулировать результатом, вам придется создать другую коллекцию и передать результат, поскольку результат фильтра является неизменяемым фильтрованным представлением исходной коллекции.

Чтобы сделать это более конкретным:

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

Конечно, это не так уж и чище (если только вы не создадите отдельный класс для своего предиката и не будете использовать его много раз), и он действительно возвращает список пользователей, а не их идентификаторы ... вам придется использовать «преобразование», чтобы получить их идентификаторы, так что лично я бы просто использовал то, что у вас есть сейчас.

0 голосов
/ 17 мая 2010

Вы можете использовать другой подход: Если возможно, просто создайте список selectedUsers, когда выбирается пользователь. IIRC, который вызывается через тщательную оценку - это означает, что вы предоставляете этот «расчет» при изменении статуса выбора, а не после него. Без контекста я не могу сказать, если это хороший способ для вас. Но в некоторых случаях это хорошо, потому что вам не нужно перебирать длинный (возможно) список.

0 голосов
/ 17 мая 2010

Вы можете написать свой собственный код для него, который сэкономит вам несколько строк кода в каждом месте, где вы применяете фильтр (за счет большего количества кода в классе 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 голосов
/ 17 мая 2010

Альтернативой фильтрации может быть ведение списка выбранных пользователей. В 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 );
        }
    } 
} 

Этот подход требует реализованного метода равных. Кстати, ваш фрагмент добавляет userId (Int?) В список типа User.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...