Почему в Java 8 нет BooleanConsumer?
Я боюсь, что это несколько глупый вопрос.
Можно ли мне сказать, почему нет BooleanConsumer
напротив BooleanSupplier
?
Есть ли какая-либо причина, кроме "потому что просто нет"?
Должен ли я создать свой собственный? Или я пропущу что-то еще?
public interface BooleanConsumer {
void accept(boolean value);
default BooleanConsumer andThen(final BooleanConsumer after) {
return v -> {
accept(v);
after.accept(v);
}
}
}
Update
Где использовать? Я пишу библиотеку, которая использует большую часть потребителей и поставщиков. Я успешно написал строку с LongConsumer
, и я столкнулся с ситуацией, ожидающей, что потребитель примет логическое значение, полученное из результата метода. Скажите Files.deleteIfExist
?
Ответы
Ответ 1
IntConsumer
и LongConsumer
необходимы, чтобы избежать накладных автобоксинга каждого значения. Гораздо эффективнее работать с исходными примитивами.
Однако для Boolean и Byte каждый возможный объект кэшируется, поэтому нет оснований избегать использования Consumer<Boolean>
или Consumer<Byte>
Ответ 2
Как показывают другие ответы, нет никаких оснований избегать Consumer<Boolean>
, но тогда нет большой причины избегать Supplier<Boolean>
, поэтому для этого требуется другое объяснение.
Аналогичный вопрос заключается в том, почему вы не можете включить значение boolean
. Ответ заключается в том, что нет необходимости, потому что вы всегда можете использовать if
или if else
.
A BooleanConsumer
действительно будет не чем иным, как конструкцией if else
, потому что метод accept()
для BooleanConsumer
всегда может быть записан в этой форме:
if (v) {
// Do something
} else {
// Do something else
}
Если вам нужно передать такой код как данные, вы можете просто передать пару Runnable
, представляющую "сделать что-то" и "сделать что-то еще". Во многих случаях вам понадобится только один из Runnable
, потому что один из двух блоков выше будет пустым.
Таким же образом нет необходимости в BooleanPredicate
, потому что это будет не что иное, как пара BooleanSupplier
, и нет необходимости в aa BooleanFunction<R>
, потому что это будет не что иное, как пара Supplier<R>
с.
В отличие от этого, невозможно разбить a BooleanSupplier
на два более простых объекта.
Ответ 3
Вы можете написать свой собственный BooleanConsumer, но чтобы сделать его действительно полезным, вам также нужно написать свой собственный BooleanStream. Есть IntStream, LongStream и DoubleStream, но нет "BooleanStream" (или "ShortStream", "FloatStream" и т.д.). Похоже, что эти примитивы считались недостаточно важными.
Вы всегда можете использовать логические объекты вместо булевых примитивов и Boolean Consumer для использования значений. Пример кода:
public class Main {
public static void main(String[] args) {
Consumer<Boolean> myConsumer = b -> System.out.println("b = " + b);
Stream.of("aa", "bb", "cc")
.map(Main::myBooleanFunction)
.forEach(myConsumer);
}
static boolean myBooleanFunction(String s) {
return s.startsWith("b");
}
}
myBooleanFunction возвращает логическое значение, но его использование на карте создает поток булевых (потому что мы находимся в родовом, не примитивном потоке. Снова у нас есть mapToInt, mapToLong, mapToDouble для создания IntStream и т.д., но нет mapToBoolean).
Если вам не нужна поддержка потоков, вы все равно можете написать и использовать "BooleanConsumer", чтобы обеспечить тип для какого-либо поведения, я бы предпочел видеть функциональный интерфейс с более конкретным и описательным именем.