Java 8 Supplier & Consumer explanation dla laika
Jako programista nie-Java uczący się Javy, czytam w tej chwili o interfejsach Supplier
i Consumer
. I nie mogę zawinąć głowy wokół ich użycia i znaczenia. Kiedy i dlaczego miałbyś używać tych interfejsów? Czy ktoś może mi podać prosty przykład laika ... uważam, że przykłady Doc nie są wystarczająco zwięzłe dla mojego zrozumienia.
7 answers
To jest dostawca:
public Integer getInteger() {
return new Random().nextInt();
}
To jest Konsument:
public void sum(Integer a, Integer b) {
System.out.println(a + b);
}
Więc w kategoriach laika, dostawca jest metodą, która zwraca pewną wartość (jak w jego wartość zwracaną). Natomiast konsument to metoda, która zużywa pewną wartość (jak w argumencie metody) i wykonuje na nich pewne operacje.
Te przekształcą się w coś takiego:
// 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);
Jeśli chodzi o użycie, podstawowym przykładem może być: Stream#forEach(Consumer)
metoda. Zajmuje konsumenta, który konsumuje element z stream, na którym iterujesz, i wykonuje pewne działania na każdym z nich. Pewnie je wydrukują.
Consumer<String> stringConsumer = (s) -> System.out.println(s.length());
Arrays.asList("ab", "abc", "a", "abcd").stream().forEach(stringConsumer);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-20 12:34:55
Powodem, dla którego masz trudności z pojęciem znaczenia funkcjonalnych interfejsów, takich jak te w java.util.function
jest to, że interfejsy zdefiniowane tutaj nie mają żadnego znaczenia! Są one obecne przede wszystkim do reprezentowania struktury, A Nie semantyki.
Jest to nietypowe dla większości interfejsów API Javy. Typowe API Javy, takie jak klasa lub interfejs, ma znaczenie i można opracować mentalny model tego, co reprezentuje i użyć go do zrozumienia operacji na nim. Rozważ Na przykład. A List
jest kontenerem innych obiektów. Mają sekwencję i indeks. Liczba obiektów znajdujących się na liście jest zwracana przez size()
. Każdy obiekt ma indeks w zakresie 0..Rozmiar - 1 (włącznie). Obiekt o indeksie i {[16] } może być odzyskany przez wywołanie list.get(i)
. I tak dalej.
Interfejsy funkcjonalne w java.util.function
nie mają takiego znaczenia. Zamiast tego są to interfejsy, które reprezentują jedynie strukturę funkcji, taką jak liczba argumenty, liczba zwracanych wartości i (czasami) to, czy argument lub wartość zwracana jest prymitywna. Tak więc mamy coś w rodzaju Function<T,R>
, które reprezentuje funkcję, która pobiera pojedynczy argument typu T i zwraca wartość typu R . To wszystko. Do czego służy ta funkcja? Może zrobić wszystko ... tak długo, jak pobiera pojedynczy argument i zwraca pojedynczą wartość. Dlatego Specyfikacja Function<T,R>
jest niewiele większa niż " reprezentuje funkcję, która przyjmuje jedną argument i daje wynik."
Oczywiście, kiedy piszemy kod, ma on znaczenie i to znaczenie musi skądś pochodzić. W przypadku interfejsów funkcjonalnych znaczenie pochodzi z kontekstu, w którym są używane. Interfejs Function<T,R>
nie ma żadnego znaczenia w izolacji. Jednak w API java.util.Map<K,V>
znajduje się:
V computeIfAbsent(K key, Function<K,V> mappingFunction)
(wildcards)
Ah, to użycie {[11] } jest "funkcją mapowania". Co to robi? W tym kontekście, jeśli key
nie jest już obecny na mapie, funkcja mapowania jest wywoływana i przekazywana kluczowi i oczekuje się, że wytworzy wartość, a wynikowa para klucz-wartość jest wstawiana do mapy.
Nie można więc patrzeć na specyfikację Function
(ani na żaden inny funkcjonalny interfejs) i próbować rozeznać, co one oznaczają. Aby zrozumieć, co oznaczają, musisz przyjrzeć się, gdzie są one używane w innych interfejsach API, a to znaczenie odnosi się tylko do tego kontekstu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-10 00:54:10
A {[4] } jest dowolną metodą, która nie pobiera argumentów i zwraca wartość. Jego zadaniem jest dosłownie dostarczenie instancji oczekiwanej klasy. Na przykład, każde odniesienie do metody "getter" jest Supplier
public Integer getCount(){
return this.count;
}
Jego odniesienie do metody instancji myClass::getCount
jest instancją Supplier<Integer>
.
A Consumer
jest dowolną metodą, która pobiera argumenty i nie zwraca niczego. Jest wywoływany ze względu na skutki uboczne. W języku Java, a Consumer
jest idiomem dla metody void
. metody "settera" są dobrym przykład:
public void setCount(int count){
this.count = count;
}
Jego odwołanie do metody instancji myClass::setCount
jest instancją Consumer<Integer>
i IntConsumer
.
A {[14] } jest dowolną metodą, która pobiera argument jednego typu i zwraca inny. Można to nazwać "transformacją". Function<A,B>
pobiera A
i zwraca B
. Warto zauważyć, że dla danej wartości A
, funkcja powinna zawsze zwracać określoną wartość B
. A
i B
w rzeczywistości mogą być tego samego typu, na przykład:
public Integer addTwo(int i){
return i+2;
}
A Klasa odwołanie metody do gettera jest również funkcją.
public Integer getCount(){
return this.count;
}
Jego odniesienie do metody klasy MyClass::getCount
jest instancją Function<MyClass,Integer>
i ToIntFunction<MyClass>
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-12 23:11:47
Dlaczego w Javie zdefiniowane są Interfejsy funkcjonalne typu Consumer/Supplier/other.util.function package : Consumer i Supplier to dwa spośród wielu wbudowanych interfejsów funkcjonalnych w Javie 8. Celem wszystkich tych wbudowanych interfejsów funkcjonalnych jest dostarczenie gotowego "szablonu" dla interfejsów funkcjonalnych posiadających wspólne deskryptory funkcji(podpisy/definicje metod funkcjonalnych).
Powiedzmy, że mamy wymagane do konwersji typu T na inny typ R. Jeśli przekazać dowolną funkcję zdefiniowaną w ten sposób jako parametr do metody, wtedy ta metoda będzie musiała zdefiniować interfejs funkcjonalny, którego funkcjonalna / abstrakcyjna metoda przyjmuje parametr typu T jako wejście i daje parametr typu R jako wyjście. Teraz, nie może być wiele scenariuszy takich jak ten i programista(s) skończy się definiowanie wielu funkcjonalnych interfejsów dla swoich potrzeb. Aby uniknąć tego rodzaju scenariusza, łatwość programowania i wprowadzenie wspólnego standardu w użyciu interfejsów funkcjonalnych, a zdefiniowano zestaw wbudowanych interfejsów funkcjonalnych, takich jak predykat, funkcja, konsument I Dostawca.
Co robi konsument : funkcjonalny interfejs konsumenta akceptuje wejście, robi coś z tym wejściem i nie daje żadnego wyjścia. Jego definicja jest taka (ze źródła Java) -
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
Tutaj accept() jest metodą funkcyjną \ abstrakcyjną, która pobiera dane wejściowe i nie zwraca żadnych danych wyjściowych. Tak więc, jeśli chcesz wprowadzić liczbę całkowitą, zrób coś z nią bez wyjścia następnie zamiast definiować własny interfejs użyj instancji Consumer.
Co robi dostawca: Interfejs funkcjonalny dostawcy nie pobiera żadnych danych wejściowych, ale zwraca dane wyjściowe. Its defined like this (from Java Source) -
@FunctionalInterface
public interface Supplier<T> {
T get();
}
Gdziekolwiek potrzebujesz funkcji, która coś zwraca, powiedzmy liczbę całkowitą, ale nie pobiera danych wyjściowych, użyj instancji Supplier.
W przypadku, gdy potrzeba większej jasności, wraz z przykładowym użyciem, interfejsów konsumentów i Dostawców, możesz odnieść się do moje wpisy na blogu o tym samym - http://www.javabrahman.com/java-8/java-8-java-util-function-consumer-tutorial-with-examples/ oraz http://www.javabrahman.com/java-8/java-8-java-util-function-supplier-tutorial-with-examples/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-09 10:37:49
1. Znaczenie
Zobacz moje odpowiedzi na moje pytanie tutaj, a także inne tutaj, ale w skrócie te nowe interfejsy zapewniają konwencję i opisowość dla każdego do użycia (+funky metody łańcuchowania, takie jak .forEach(someMethod().andThen(otherMethod()))
2. Różnice
Konsument : bierze coś, robi coś, nic nie zwraca: void accept(T t)
Dostawca: nic nie bierze, coś zwraca: T get()
(odwrotność konsumenta, w zasadzie uniwersalna metoda "getter")
3. Użycie
// Consumer: It takes something (a String) and does something (prints it)
List<Person> personList = getPersons();
personList.stream()
.map(Person::getName)
.forEach(System.out::println);
Dostawca: zawiń powtarzalny kod, np. czas wykonania kodu
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;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:25
W kategoriach laików,
Dostawca dostarczy dane, ale bez konsumowania żadnych danych. W terminach programistycznych metoda, która nie przyjmuje żadnego argumentu, ale zwraca wartość. Służy do generowania nowych wartości.
Http://codedestine.com/java-8-supplier-interface/
Konsument konsumuje Dane i nie zwraca żadnych danych. W terminologii programowej metoda, która pobiera wiele argumentów i nie zwraca żadnej wartości.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-07 11:47:30
Consumer i supplier to Interfejsy dostarczane przez Javę. Consumer is use for iterate over the list elements and supplier is use for supply object ' s
Możesz łatwo zrozumieć dzięki demonstracji kodu.
Consumer
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);
}
}
Dostawca
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());
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-20 07:21:37