У 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 синтаксис лямбда настільки стислий, що є синтаксичний недолік у написанні виклику статичного методу.
Це просто синтаксичне порівняння. Мабуть, невелика перевага простору, якби існував єдиний глобальний завжди істинний предикат, порівняно з x -> true
подіями, рознесеними по декількох класах, кожен з яких створив би свій власний предикатний екземпляр. Це те, що вас хвилює? Заощадження не здалися переконливими, тому, ймовірно, вони не були додані в першу чергу. Але це може бути переглянути для майбутнього випуску.
ОНОВЛЕННЯ 2015-04-24
Ми розглянули додавання різноманітних статичних, іменованих функцій, таких як Predicate.alwaysTrue
, Runnable.noop
тощо, і вирішили більше не додавати в майбутні версії Java SE.
Звичайно, є щось значення у чомусь, що має ім’я порівняно з виписаною лямбда, але це значення досить мало. Ми очікуємо, що люди навчаться читати і писати, x -> true
а () -> { }
їх використання стане ідіоматичним. Навіть значення Function.identity()
над x -> x
сумнівом.
Існує невелика перевага в продуктивності використання повторно використання існуючої функції замість того, щоб оцінювати виписану лямбда, але ми очікуємо, що використання таких функцій буде настільки малим, що така перевага була б незначною, звичайно не варто розробити API.
Голгер також згадував у коментарях можливість оптимізації складених функцій, таких як Predicate.or
і такі. Це також вважалося ( JDK-8067971 ), але вважалося дещо крихким та схильним до помилок, і траплялося досить рідко, що не варто було докладати зусиль.
Дивіться також цей запис Ламбда-FAQ .
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 напевно відсутнє ключове слово (читати: keyletter) для "невикористаного параметра". Сподіваюсь, що щось подібне з’явиться у Java 9 (або принаймні: Java, що завгодно до того, як я помру ^^)
Без гуави
Boolean.TRUE::booleanValue
Predicate
, як це не бере аргументу.
(foo)->{return true;}
це найкраще, що я можу зробити, я хочу кращого. Але ви піднялиx->true
, що набагато краще і пом'якшує перше питання. Другий випуск - логіка проти статичного оголошення. Якщо я використовуюx->true
, все ще є логіка, яку я можу ненароком викрутити (наприкладx->!true
). Але, маючиPredicate.alwaysTrue()
місце, для логічної помилки немає місця, оскільки існує лише один або два подібних методу. Плюс я отримую код IDE безкоштовно.x->true
майже добре, але я все-таки написавPredicate.alwaysTrue()
метод з причин, зазначених вище.