Java 8 объяснение поставщика и потребителя для непрофессионала
как программист не-Java, изучающий Java, я читаю о Supplier
и Consumer
интерфейсов на данный момент. И я не могу разобраться в их значении. Когда и почему вы будете использовать эти интерфейсы? Может кто-нибудь дать мне простой пример непрофессионала этого... я нахожу примеры Doc недостаточно краткими для моего понимания.
7 ответов
Это поставщика:
public Integer getInteger() {
return new Random().nextInt();
}
Это потребителя:
public void sum(Integer a, Integer b) {
System.out.println(a + b);
}
таким образом, в терминах непрофессионала поставщик-это метод, который возвращает некоторое значение (как в его возвращаемом значении). В то время как потребитель-это метод, который потребляет некоторое значение (как в аргументе метода) и выполняет некоторые операции над ними.
те превратятся во что-то вроде этого:
// new operator itself is a supplier, of the reference to the newly created object
Supplier<List<String>> listSupplier = ArrayList::new;
Consumer<String> printConsumer = a1 -> System.out.println(a1);
BiConsumer<Integer, Integer> sumConsumer = (a1, a2) -> System.out.println(a1 + a2);
Что касается использования, самым основным примером будет:Stream#forEach(Consumer)
метод. Это требует Потребитель, который потребляет элемент из потока, на котором вы выполняете итерацию, и выполняет некоторые действия над каждым из них. Вероятно, распечатать их.
Consumer<String> stringConsumer = (s) -> System.out.println(s.length());
Arrays.asList("ab", "abc", "a", "abcd").stream().forEach(stringConsumer);
причина у вас возникли трудности с пониманием значения функциональных интерфейсов, таких как java.util.function
то, что интерфейсы, определенные здесь, не имеют никакого значения! Они присутствуют прежде всего для представления структура, а не семантика.
это нетипично для большинства API Java. Типичный API Java, такой как класс или интерфейс, имеет значение, и вы можете разработать ментальную модель для того, что он представляет, и использовать это для понимания операции на нем. Считать java.util.List
например. А List
является контейнером для других объектов. У них есть последовательность и индекс. Количество объектов, содержащихся в списке, возвращается size()
. Каждый объект имеет индекс в диапазоне 0..размер-1 (включительно). Объект по индексу я можно получить, позвонив list.get(i)
. И так далее.
функциональные интерфейсы в java.util.function
не имеют такого значения. Вместо этого они являются интерфейсами, которые просто представляют структура функции, такие как количество аргументов, количество возвращаемых значений и (иногда) является ли аргумент или возвращаемое значение примитивом. Таким образом, у нас есть что-то вроде Function<T,R>
, который представляет собой функцию, которая принимает один аргумент типа T и возвращает значение типа R. Вот и все. Что делает эта функция? Ну, он может все ... пока он принимает один аргумент и возвращает одно значение. Вот почему спецификация для Function<T,R>
немного больше ,чем " представляет функцию, которая принимает один аргумент и дает результат."
java.util.Map<K,V>
API, есть следующее:
V computeIfAbsent(K key, Function<K,V> mappingFunction)
(подстановочные знаки для краткость)
Ах, это использование Function
является "функцией отображения". Что это значит? В этом контексте, если key
еще не присутствует на карте, функция отображения вызывается и передается ключ и, как ожидается, произведет значение, и результирующая пара ключ-значение вставляется в карту.
поэтому вы не можете посмотреть спецификацию для Function
(или любой другой функциональный интерфейс, если на то пошло) и попытаться понять, что они означают. Ты должен посмотрите, где они используются в других API, чтобы понять, что они означают, и это значение применимо только к этому контексту.
A Supplier
- это любой метод, который не принимает никаких аргументов и возвращает значение. Его задача-буквально предоставить экземпляр ожидаемого класса. Например, каждая ссылка на метод "getter" является Supplier
public Integer getCount(){
return this.count;
}
ссылка на метод экземпляра myClass::getCount
пример Supplier<Integer>
.
A Consumer
- это любой метод, который принимает аргументов и ничего не возвращает. Оно вызвано для своих побочных эффектов. В терминах Java a Consumer
это идиома для void
метод. хорошим примером являются методы "сеттера":
public void setCount(int count){
this.count = count;
}
ссылка на метод экземпляра myClass::setCount
пример Consumer<Integer>
и IntConsumer
.
A Function<A,B>
- это любой метод, который принимает аргумент одного типа, и возвращает другое. Это можно назвать "трансформацией". The Function<A,B>
принимает A
и возвращает B
. Примечательно, что для заданного значения A
функция всегда должна возвращать значение B
. A
и B
может на самом деле быть того же типа, например:
public Integer addTwo(int i){
return i+2;
}
ссылка метода класса на геттер также является функцией.
public Integer getCount(){
return this.count;
}
ссылка на метод класса MyClass::getCount
пример Function<MyClass,Integer>
и ToIntFunction<MyClass>
.
почему потребитель / поставщик / другие функциональные интерфейсы определены в java.утиль.пакет функций: потребитель и поставщик-это два, среди многих, встроенных функциональных интерфейса, предоставляемых в Java 8. Цель всех этих встроенных функциональных интерфейсов-предоставить готовый "шаблон" для функциональных интерфейсов, имеющих общие дескрипторы функций(сигнатуры/определения функциональных методов).
допустим, у нас есть необходимое для преобразования типа T в другой тип R. Если мы пройдем!--7-->любой функция, определенная как это в качестве параметра метода, тогда этот метод должен будет определить функциональный интерфейс, функциональный / абстрактный метод которого принимает параметр типа T в качестве входного и дает параметр типа R в качестве выходного. Теперь может быть много сценариев, подобных этому, и программист(ы) в конечном итоге определит несколько функциональных интерфейсов для своих нужд. Чтобы избежать такого сценария, простота программирования и общих стандартов в использовании определены функциональные интерфейсы, набор встроенных функциональных интерфейсов, таких как предикат, функция, потребитель и поставщик.
что делает потребитель: интерфейс потребителя функциональный принимает входной сигнал, делает что-то с этим входным сигналом и не дает никакой выход. Его определение похоже на это (из источника Java) -
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
здесь accept () - это функциональный\абстрактный метод, который принимает вход и не возвращает вывода. Итак, если вы хотите ввести Integer, сделайте что-то с ним без вывода, а затем вместо определения собственного интерфейса используйте экземпляр Consumer.
что делает поставщик: интерфейс поставщика функциональный не принимает никакой входной сигнал но возвращает выход. Его определяется так(из источника Java) -
@FunctionalInterface
public interface Supplier<T> {
T get();
}
везде, где вам нужна функция, которая возвращает что-то, скажем, целое число, но не выводит экземпляр поставщика.
в случае большей ясности, наряду с примерами использование интерфейсов потребителя и поставщика необходимо, тогда вы можете ссылаться на мои сообщения в блоге на то же самое - http://www.javabrahman.com/java-8/java-8-java-util-function-consumer-tutorial-with-examples/ и http://www.javabrahman.com/java-8/java-8-java-util-function-supplier-tutorial-with-examples/
1. Смысл
посмотреть мои ответы на мой вопрос здесь и здесь, но вкратце эти новые интерфейсы обеспечивают и описательности для всех, чтобы использовать (+фанки метод цепочки, такие как .forEach(someMethod().andThen(otherMethod()))
2. Различия
потребитель: что-то берет, что-то делает, ничего не возвращает: void accept(T t)
поставщик: принимает ничего, возвращает что-то : T get()
(реверс потребителя, в основном универсальный метод "геттера")
3. Использование
// Consumer: It takes something (a String) and does something (prints it)
List<Person> personList = getPersons();
personList.stream()
.map(Person::getName)
.forEach(System.out::println);
поставщик: оберните повторяющийся код, например, время выполнения кода
public class SupplierExample {
public static void main(String[] args) {
// Imagine a class Calculate with some methods
Double result1 = timeMe(Calculate::doHeavyComputation);
Double result2 = timeMe(Calculate::doMoreComputation);
}
private static Double timeMe(Supplier<Double> code) {
Instant start = Instant.now();
// Supplier method .get() just invokes whatever it is passed
Double result = code.get();
Instant end = Instant.now();
Duration elapsed = Duration.between(start,end);
System.out.println("Computation took:" + elapsed.toMillis());
return result;
}
}
в непрофессиональных терминах,
поставщик будет поставлять данные, но не потребляя никаких данных. В терминах программирования Метод, который не принимает никаких аргументов, но возвращает значение. Он используется для генерации новых значений.
http://codedestine.com/java-8-supplier-interface/
потребитель будет потреблять информацию, но не возвращает никаких данных. С точки зрения программирования Метод, который принимает несколько аргументов и не возвращает никакого значения.
потребитель и поставщик-это интерфейсы, предоставляемые java. Потребитель используется для итерации по элементам списка, а поставщик - для
вы можете легко понять с демонстрацией кода.
потребитель
package com.java.java8;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
/**
* The Class ConsumerDemo.
*
* @author Ankit Sood Apr 20, 2017
*/
public class ConsumerDemo {
/**
* The main method.
*
* @param args
* the arguments
*/
public static void main(String[] args) {
List<String> str = new ArrayList<>();
str.add("DEMO");
str.add("DEMO2");
str.add("DEMO3");
/* Consumer is use for iterate over the List */
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String t) {
/* Print list element on consile */
System.out.println(t);
}
};
str.forEach(consumer);
}
}
package com.java.java8;
import java.util.function.Supplier;
/**
* The Class SupplierDemo.
*
* @author Ankit Sood Apr 20, 2017
*/
public class SupplierDemo {
/**
* The main method.
*
* @param args
* the arguments
*/
public static void main(String[] args) {
getValue(() -> "Output1");
getValue(() -> "OutPut2");
}
/**
* Gets the value.
*
* @param supplier
* the supplier
* @return the value
*/
public static void getValue(Supplier<?> supplier) {
System.out.println(supplier.get());
}
}