Используйте Collection#removeIf для изменения коллекции на месте. (Обратите внимание: в этом случае предикат удалит объекты, удовлетворяющие предикату):
persons.removeIf(p -> p.getAge() <= 16);
lambdaj позволяет фильтровать коллекции без написания циклов или внутренних классов:
Можете ли вы представить что-нибудь более читаемое?
Отказ от ответственности: я участник lambdaj
Ответ 2
Предполагая, что вы используете Java 1.5 и что вы не можете добавлять коллекции Google, я бы сделал что-то очень похожее на то, что сделали ребята из Google. Это небольшое изменение комментариев Джона.
Сначала добавьте этот интерфейс в свою кодовую базу.
Его разработчики могут ответить, когда определенный предикат является истинным для определенного типа. Например. Если T были User и AuthorizedUserPredicate<User> реализует IPredicate<T>, то AuthorizedUserPredicate#apply возвращает, разрешено ли переданное в User.
Затем в каком-нибудь служебном классе вы могли бы сказать
publicstatic <T> Collection<T> filter(Collection<T> target, IPredicate<T> predicate) { Collection<T> result = newArrayList<T>(); for (T element: target) { if (predicate.apply(element)) { result.add(element); } } return result; }
Итак, предполагая, что вы используете вышеуказанное, может быть
Predicate<User> isAuthorized = newPredicate<User>() { publicbooleanapply(User user) { // binds a boolean method in User to a reference return user.isAuthorized(); } }; // allUsers is a Collection<User> Collection<User> authorizedUsers = filter(allUsers, isAuthorized);
Если производительность при линейной проверке вызывает беспокойство, то я мог бы захотеть иметь объект домена, который имеет целевую коллекцию. Объект домена, имеющий целевую коллекцию, будет иметь логику фильтрации для методов, которые инициализируют, добавляют и устанавливают целевую коллекцию.
Обновить:
В служебном классе (скажем, Predicate ) я добавил метод select с параметром для значения по умолчанию, когда предикат не возвращает ожидаемое значение, а также статическое свойство для параметров, которые будут использоваться внутри нового IPredicate .
publicstatic <T> Collection<T> filter(Collection<T> target, IPredicate<T> predicate) { Collection<T> result = newArrayList<T>(); for (T element : target) { if (predicate.apply(element)) { result.add(element); } } return result; }
publicstatic <T> T select(Collection<T> target, IPredicate<T> predicate) { Tresult=null; for (T element : target) { if (!predicate.apply(element)) continue; result = element; break; } return result; }
publicstatic <T> T select(Collection<T> target, IPredicate<T> predicate, T defaultValue) { Tresult= defaultValue; for (T element : target) { if (!predicate.apply(element)) continue; result = element; break; } return result; } }
В следующем примере выполняется поиск отсутствующих объектов между коллекциями:
В следующем примере выполняется поиск экземпляра в коллекции и возвращается первый элемент коллекции в качестве значения по умолчанию, когда экземпляр не найден:
Прошло несколько лет с тех пор, как я (Алан) впервые опубликовал этот ответ, и я все еще не могу поверить, что набираю SO баллов за этот ответ. В любом случае, теперь, когда Java 8 ввела в язык замыкания, мой ответ теперь был бы значительно другим и более простым. С Java 8 нет необходимости в отдельном статическом служебном классе. Итак, если вы хотите найти 1-й элемент, соответствующий вашему предикату.
finalUserServiceuserService= ... // perhaps injected IoC final Optional<UserModel> userOption = userCollection.stream().filter(u -> { booleanisAuthorized= userService.isAuthorized(u); return isAuthorized; }).findFirst();
API JDK 8 для опций имеет возможность get(), isPresent(), orElse(defaultUser)orElseGet(userSupplier) и orElseThrow(exceptionSupplier), а также другие "монадические" функции, такие как map, flatMap и filter.
Если вы хотите просто собрать всех пользователей, которые соответствуют предикату, то используйте Collectors, чтобы завершить поток в нужной коллекции.
finalUserServiceuserService= ... // perhaps injected IoC final List<UserModel> userOption = userCollection.stream().filter(u -> { booleanisAuthorized= userService.isAuthorized(u); return isAuthorized; }).collect(Collectors.toList());
Смотрите Здесь больше примеров того, как работают потоки Java 8.
Теперь, чтобы сделать ее более читаемой, вы можете обернуть ее в служебный метод. Затем придумайте интерфейс IPredicate, создайте анонимную реализацию этого интерфейса и сделайте что-то вроде: