У 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()метод з причин, зазначених вище.