Java представила поддержку функционального программирования в выпуске Java версии 8. Этот конкретный выпуск также представил несколько новых концепций, в частности лямбда-выражения, ссылки на методы и множество функциональных интерфейсов. При обсуждении последних, есть несколько функциональных интерфейсов, а именно Потребитель (Consumer), Поставщик (Supplier), Предикат (Predicat) и Функция (Function), которые являются наиболее важными. В этой статье мы о них и поговорим.  Consumer — это функциональный интерфейс, который принимает один параметр на вход и не возвращает никаких выходных данных. На языке непрофессионала, как следует из названия, реализация этого интерфейса потребляет вводимые данные. Пользовательский интерфейс имеет два метода:  Метод accept является единым абстрактным методом (SAM), который принимает один аргумент типа T. Тогда как другой метод andThen является методом по умолчанию и используется для композиции.  Ниже приведен пример интерфейса consumer. Мы создали потребительскую реализацию, которая использует строку, а затем просто выводит ее на экран. Метод forEach принимает реализацию потребительского интерфейса.  В следующем примере демонстрируется использование составления нескольких реализаций интерфейса consumer для создания цепочки потребителей.Ниже мы создали двух потребителей: один преобразует список элементов в строки верхнего регистра, а другой выводит строку верхнего регистра.  Интерфейс Consumer имеет специфические типы реализаций для типов integer, double и long -> IntConsumer, DoubleConsumer и LongConsumer, как показано ниже: Supplier — это простой интерфейс, указывающий, что данная реализация является поставщиком какого то результа. Этот интерфейс, однако, не накладывает никаких дополнительных ограничений, которые реализация поставщика должна возвращать при каждом новом получении результата. У поставщика есть только один метод get() и нет никаких других методов по умолчанию или статических методов. Интерфейс поставщик имеет свои примитивные варианты, такие как IntSupplier, DoubleSupplier и т. д., как показано ниже. Обратите внимание, что имя метода — get() используется для универсального интерфейса поставщика. Однако для примитивных вариантов этот метод соответствует примитивному типу. Одно из основных применений этого интерфейса это использование для включения отложенного выполнения. Это означает отсрочку выполнения до тех пор, пока оно не понадобится. Например, в классе Optional есть метод orElseGet. Этот метод срабатывает, если у option нет данных. Это показано ниже: Интерфейс Predicate представляет собой логическую функцию аргумента. Он в основном используется для фильтрации данных из потока (stream) Java. Метод фильтра потока принимает предикат для фильтрации данных и возврата нового потока, удовлетворяющего предикату. У предиката есть метод test(), который принимает аргумент и возвращает логическое значение. В приведенном выше примере мы создали предикат, который проверяет имена, начинающиеся с S. Этот предикат передается потоку. Predicate также предоставляет несколько стандартных и статических методов для композиции и других целей: В следующем примере демонстрируется использование и метод для составления цепочки предикатов. Интерфейс Function — это более общий интерфейс, который принимает один аргумент и выдает результат. В нем применяется единый абстрактный метод (SAM), который принимает аргумент типа T и выдает результат типа R. Одним из распространенных вариантов использования этого интерфейса является метод Stream.map. Пример использования  показан ниже: Введение функционального программирования представило новую парадигму языка Java. И интерфейсы Consumer, Supplier, Predicate и Function играют решающую роль в том, как это реализовано в Java. Освоение этих интерфейсов и связанных с ними примитивных вариантов, безусловно, помогает писать более качественный функциональный код. Источник: статьяОдногоУмногоПарня