У Google Guava есть предикат, который всегда возвращаетсяtrue
. Есть ли в Java 8 что-то подобное Predicate
? Я знаю, что могу использовать (foo)->{return true;}
, но мне нужно что-то готовое, аналогичное Collections.emptySet()
.
У Google Guava есть предикат, который всегда возвращаетсяtrue
. Есть ли в Java 8 что-то подобное Predicate
? Я знаю, что могу использовать (foo)->{return true;}
, но мне нужно что-то готовое, аналогичное Collections.emptySet()
.
Ответы:
В Java 8 нет встроенных предикатов всегда-истинно и всегда-ложно. Самый краткий способ их записи -
x -> true
и
x -> false
Сравните это с
Predicates.alwaysTrue() // Guava
и, наконец, к анонимному внутреннему классу:
new Predicate<Object>() {
public boolean test(Object x) {
return true;
}
}
Вероятно, причина того, что Guava имеет эти встроенные предикаты, заключается в том, что существует огромное синтаксическое преимущество вызова статического метода над анонимным внутренним классом. В Java 8 лямбда-синтаксис настолько лаконичен, что запись вызова статического метода является синтаксическим недостатком .
Однако это просто синтаксическое сравнение. Вероятно, есть небольшое преимущество в пространстве, если бы существовал единственный глобальный предикат Always-true по сравнению с x -> true
экземплярами, распределенными по нескольким классам, каждый из которых создал бы свой собственный экземпляр предиката. Это то, что вас беспокоит? Экономия не казалась убедительной, возможно, поэтому ее и не добавили. Но это может быть пересмотрено для будущего выпуска.
ОБНОВЛЕНИЕ 2015-04-24
Мы рассмотрели возможность добавления множества статических именованных функций, таких как Predicate.alwaysTrue
, Runnable.noop
и т. Д., И решили не добавлять больше в будущих версиях Java SE.
Конечно, есть некоторая ценность в том, что имеет имя по сравнению с записанной лямбдой, но это значение довольно мало. Мы ожидаем , что люди научатся читать и писать , x -> true
и () -> { }
и что их использование будет идиоматическое. Даже ценность Function.identity()
over x -> x
сомнительна.
Повторное использование существующей функции вместо оценки записанного лямбда дает небольшое преимущество в производительности, но мы ожидаем, что использование этих функций будет настолько малым, что такое преимущество будет незначительным и, конечно, не стоит раздувания API.
Хольгер также упомянул в комментариях возможность оптимизации составных функций, таких как Predicate.or
и такие. Это также рассматривалось ( JDK-8067971 ), но было сочтено несколько хрупким и подверженным ошибкам, а также происходящим достаточно редко, поэтому не стоило усилий для реализации.
См. Также этот раздел часто задаваемых вопросов о лямбде.
Predicate.alwaysTrue()
тобой тоже можно облажаться, если ты случайно написал Predicate.alwaysFalse()
.
alwaysTrue()
и alwaysFalse()
. Что касается реальной лямбды, у меня есть много вариантов; По сути, я каждый раз реконструирую формулу. По сути, alwaysTrue()
это семантическая метка того, что я хочу делать; x->true
фактически делает это каждый раз заново. Не огромное, но заслуживающее внимания.
Predicate.alwaysTrue()
и Predicate.alwaysFalse()
экземпляров в том, что они могут быть признаны комбинируя методы , как Predicate.or
, Predicate.and
и Predicate.negate()
. Это позволило бы предварительно инициализировать Predicate
переменные с помощью alwaysTrue()
предикатов и добавлять их путем объединения and
без дополнительных затрат. Поскольку лямбда-выражения не имеют гарантии идентичности объекта, это может не сработать x->true
. Между прочим, если у меня есть класс X
с static
методом y(){return true;}
, использование X::y
даже короче, x->true
но не очень рекомендуется…
x -> true
Недостаток идиомы состоит в том, что мне приходится использовать переменную без использования. Это создает ненужную нагрузку на мозг, а также вызывает предупреждение в моей IDE. Я пробовал использовать _ -> true
, но это синтаксическая ошибка. В Java определенно отсутствует ключевое слово (читай: клавиатурная буква) для «неиспользуемого параметра». Надеюсь, что что-то подобное появится в Java 9 (или, по крайней мере, в Java - что угодно, прежде чем я умру ^^)
Без гуавы
Boolean.TRUE::booleanValue
Predicate
, поскольку не требует аргументов.
(foo)->{return true;}
это лучшее, что я могу сделать, я хочу лучшего. Но вы поднялиx->true
, что намного лучше и смягчает первую проблему. Вторая проблема связана с объявлением логики и статики. Если я используюx->true
, все еще присутствует логика, которую я могу случайно испортить (напримерx->!true
). НоPredicate.alwaysTrue()
здесь нет места для логической ошибки, так как есть только один или два похожих метода. Плюс я получаю автозавершение кода IDE бесплатно.x->true
почти нормально, но я все же написалPredicate.alwaysTrue()
метод по причинам выше.