Я хочу фильтровать на java.util.Collection
основе предиката.
java
collections
filter
Кевин Вонг
источник
источник
persons.removeIf(p -> p.getAge() <= 16);
Предполагая, что вы используете Java 1.5 , и что вы не можете добавить Google Collections , я бы сделал нечто очень похожее на то, что сделали ребята из Google. Это небольшое изменение в комментариях Джона.
Сначала добавьте этот интерфейс в вашу кодовую базу.
Его разработчики могут ответить, когда определенный предикат является истинным для определенного типа. Например, если
T
былиUser
иAuthorizedUserPredicate<User>
реализуетIPredicate<T>
, тоAuthorizedUserPredicate#apply
возвращает ли переданные вUser
авторизован .Тогда в каком-то служебном классе вы могли бы сказать
Таким образом, предполагая, что у вас есть использование выше, может быть
Если производительность при линейной проверке вызывает беспокойство, я мог бы захотеть иметь объект домена, имеющий целевую коллекцию. Доменный объект, имеющий целевую коллекцию, будет иметь логику фильтрации для методов, которые инициализируют, добавляют и устанавливают целевую коллекцию.
ОБНОВИТЬ:
В служебном классе (скажем, Predicate) я добавил метод select с опцией для значения по умолчанию, когда предикат не возвращает ожидаемое значение, а также статическое свойство для параметров, которые будут использоваться внутри нового IPredicate.
В следующем примере ищутся отсутствующие объекты между коллекциями:
В следующем примере выполняется поиск экземпляра в коллекции и возвращается первый элемент коллекции в качестве значения по умолчанию, если экземпляр не найден:
ОБНОВЛЕНИЕ (после выпуска Java 8):
Прошло несколько лет с тех пор, как я (Алан) впервые опубликовал этот ответ, и я до сих пор не могу поверить, что набираю ТАК очки за этот ответ. Во всяком случае, теперь, когда Java 8 ввела замыкания в языке, мой ответ теперь будет значительно другим и более простым. В Java 8 нет необходимости в отдельном статическом служебном классе. Так что если вы хотите найти 1-й элемент, который соответствует вашему предикату.
JDK 8 API для опций имеет возможность
get()
,isPresent()
,orElse(defaultUser)
,orElseGet(userSupplier)
иorElseThrow(exceptionSupplier)
, а также другую «монадическую» функция , такие какmap
,flatMap
иfilter
.Если вы хотите просто собрать всех пользователей, которые соответствуют предикату, то используйте
Collectors
для завершения потока в нужной коллекции.Смотрите здесь для большего количества примеров того, как работают потоки Java 8.
источник
val authorized = for (user <- users if user.isAuthorized) yield user
Используйте CollectionUtils.filter (Collection, Predicate) от Apache Commons.
источник
«Лучший» способ - это слишком широкий запрос. Это "самый короткий"? «Самый быстрый»? "Удобочитаемый"? Фильтр на месте или в другую коллекцию?
Простейший (но не самый читаемый) способ - выполнить итерацию и использовать метод Iterator.remove ():
Теперь, чтобы сделать его более читабельным, вы можете превратить его в служебный метод. Затем придумайте интерфейс IPredicate, создайте анонимную реализацию этого интерфейса и сделайте что-то вроде:
где filterInPlace () выполняет итерацию коллекции и вызывает Predicate.keepIt (), чтобы узнать, будет ли экземпляр храниться в коллекции.
Я не вижу оправдания для привлечения сторонней библиотеки только для этой задачи.
источник
stream()
особенность, но не каждый может поиграть с новейшими игрушками: PРассмотрим Google Collections для обновленной структуры Collections, которая поддерживает дженерики.
ОБНОВЛЕНИЕ : Библиотека коллекций Google устарела. Вместо этого вы должны использовать последнюю версию Guava . Он все еще имеет все те же расширения для структуры коллекций, включая механизм фильтрации на основе предиката.
источник
Ждите Java 8:
источник
personList.removeIf(p -> p.age < 30);
Меньше многословно. Кроме того, я слышал разговоры о том, чтобы начать реализовывать apis, которые принимают и возвращаютStream
s, а неCollection
s, потому чтоStream
s очень полезны и быстры, но идти к ним и из них идет медленно.Начиная с раннего выпуска Java 8, вы можете попробовать что-то вроде:
Например, если у вас есть список целых чисел, и вы хотите отфильтровать числа, которые> 10, а затем распечатать эти числа на консоли, вы можете сделать что-то вроде:
источник
Я добавлю RxJava в кольцо, которое также доступно на Android . RxJava не всегда может быть лучшим вариантом, но он даст вам больше гибкости, если вы захотите добавить больше преобразований в свою коллекцию или обработать ошибки во время фильтрации.
Вывод:
Более подробную информацию о RxJava
filter
можно найти здесь .источник
Настройка:
Использование:
источник
Как насчет простой и понятной Java?
Простой, читаемый и легкий (и работает в Android!) Но если вы используете Java 8, вы можете сделать это в одной приятной строке:
Обратите внимание, что toList () статически импортируется
источник
Вы уверены, что хотите отфильтровать саму коллекцию, а не итератор?
см. org.apache.commons.collections.iterators.FilterIterator
или используя версию 4 apache commons org.apache.commons.collections4.iterators.FilterIterator
источник
Давайте посмотрим, как фильтровать встроенный список JDK и список MutableList с использованием коллекций Eclipse .
Если вы хотите отфильтровать числа меньше 3, вы ожидаете следующих результатов.
Вот как вы можете фильтровать, используя лямбду Java 8 в качестве
Predicate
.Вот как вы можете фильтровать, используя анонимный внутренний класс в качестве
Predicate
.Вот некоторые альтернативы фильтрации списков JDK и MutableList коллекций Eclipse с использованием фабрики Predicates .
Вот версия, которая не выделяет объект для предиката, используя вместо этого фабрику Predicates2 с
selectWith
методом, который принимаетPredicate2
.Иногда вы хотите отфильтровать отрицательное условие. Для этого существует специальный метод в коллекциях Eclipse
reject
.Метод
partition
вернет две коллекции, содержащие элементы, выбранные и отклоненныеPredicate
.Примечание: я являюсь коммиттером для Eclipse Collections.
источник
removeIf
списке или установить для примитивов?С ForEach DSL вы можете написать
Для данной коллекции [Быстрый, коричневый, лиса, прыжки, через, ленивый, собака] это приводит к [быстрому, коричневому, прыжки, через, ленивый], то есть все строки длиннее трех символов.
Все стили итераций, поддерживаемые ForEach DSL,
AllSatisfy
AnySatisfy
Collect
Counnt
CutPieces
Detect
GroupedBy
IndexOf
InjectInto
Reject
Select
Для получения более подробной информации, пожалуйста, обратитесь к https://www.iam.unibe.ch/scg/svn_repos/Sources/ForEach
источник
Метод Collections2.filter (Collection, Predicate) в библиотеке Google Guava делает именно то, что вы ищете.
источник
Поскольку java 9
Collectors.filtering
включен:При этом фильтрация должна быть:
Пример:
источник
Это, в сочетании с отсутствием реальных замыканий, является моей самой большой проблемой для Java. Честно говоря, большинство методов, упомянутых выше, довольно легко читать и ДЕЙСТВИТЕЛЬНО эффективно; однако, потратив время на .Net, Erlang и т. д., понимание списка, интегрированное на уровне языка, делает все намного чище. Без дополнений на уровне языка Java не может быть настолько чистым, как многие другие языки в этой области.
Если производительность очень важна, то коллекции Google - это то, что нужно (или напишите собственную простую утилиту предикатов). Синтаксис лямбдажа более понятен для некоторых людей, но он не так эффективен.
А потом есть библиотека, которую я написал. Я буду игнорировать любые вопросы, касающиеся его эффективности (да, это так плохо) ...... Да, я знаю, что он основан на отражениях, и нет, на самом деле я его не использую, но он работает:
ИЛИ
источник
JFilter http://code.google.com/p/jfilter/ лучше всего подходит для ваших требований.
JFilter - это простая и высокопроизводительная библиотека с открытым исходным кодом для запроса коллекции Java-бинов.
Ключевая особенность
источник
Я написал расширенный класс Iterable, который поддерживает применение функциональных алгоритмов без копирования содержимого коллекции.
Применение:
Код выше на самом деле будет выполняться
источник
Используйте механизм сбора запросов (CQEngine) . На сегодняшний день это самый быстрый способ сделать это.
См. Также: Как вы запрашиваете коллекции объектов в Java (Criteria / SQL-like)?
источник
Некоторые действительно отличные ответы здесь. Я бы хотел, чтобы текст был максимально простым и читабельным:
источник
Простое решение до Java8:
К сожалению, это решение не является полностью общим, выводя список, а не тип данной коллекции. Кроме того, привлечение библиотек или написание функций, которые обертывают этот код, кажется мне излишним, если условие не сложное, но тогда вы можете написать функцию для условия.
источник
https://code.google.com/p/joquery/
Поддерживает разные возможности,
Данная коллекция,
типа,
Фильтр
Java 7
Java 8
Также,
Сортировка (также доступна для Java 7)
Группировка (также доступна для Java 7)
Объединения (также доступно для Java 7)
Данный,
Может быть присоединен как,
Выражения
источник
Мой ответ основан на этом от Кевина Вонга, здесь как однострочный, использующий
CollectionUtils
от весны и лямбда- выражения Java 8 .Это так же кратко и читабельно, как и любая альтернатива, которую я видел (без использования библиотек на основе аспектов)
Spring CollectionUtils доступен с весенней версии 4.0.2.RELEASE, и помните, что вам нужен JDK 1.8 и языковой уровень 8+.
источник
Используя
java 8
, в частностиlambda expression
, вы можете сделать это просто, как показано ниже:где для каждой
product
внутреннейmyProducts
коллекции, еслиprod.price>10
, а затем добавить этот продукт в новый отфильтрованный список.источник
Мне нужно было отфильтровать список в зависимости от значений, уже присутствующих в списке. Например, удалите все значения, следующие ниже, чем текущее значение. {2 5 3 4 7 5} -> {2 5 7}. Или, например, удалить все дубликаты {3 5 4 2 3 5 6} -> {3 5 4 2 6}.
Это будет использоваться следующим образом.
источник
С гуавой:
источник
В Java 8 вы можете напрямую использовать этот метод фильтра, а затем сделать это.
источник