Подтвердить что ты не робот

Почему в 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?

4b9b3361

Ответ 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", чтобы обеспечить тип для какого-либо поведения, я бы предпочел видеть функциональный интерфейс с более конкретным и описательным именем.