Java 8 Fournisseur et consommateur explication pour le profane


En tant que programmeur non Java apprenant Java, je lis sur les interfaces Supplier et Consumer en ce moment. Et je ne peux pas comprendre leur utilisation et leur signification. Quand et pourquoi utiliseriez-vous ces interfaces? Quelqu'un peut-il me donner un exemple simple de profane de cela I je trouve que les exemples de Doc ne sont pas assez succincts pour ma compréhension.

Author: jrtapsell, 2015-02-09

7 answers

C'est le Fournisseur:

public Integer getInteger() {
    return new Random().nextInt();
}

C'est le consommateur:

public void sum(Integer a, Integer b) {
    System.out.println(a + b);
}

Donc, en termes simples, un fournisseur est une méthode qui renvoie une certaine valeur (comme dans sa valeur de retour). Alors que, un consommateur est une méthode qui consomme une certaine valeur (comme dans l'argument de la méthode) et effectue certaines opérations sur eux.

Ceux-ci se transformeront en quelque chose comme ceux-ci:

// 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);

En ce qui concerne l'utilisation, l'exemple très basique serait: Stream#forEach(Consumer) méthode. Il prend un consommateur, qui consomme l'élément du flux sur lequel vous itérez et effectue une action sur chacun d'eux. Probablement les imprimer.

Consumer<String> stringConsumer = (s) -> System.out.println(s.length());
Arrays.asList("ab", "abc", "a", "abcd").stream().forEach(stringConsumer);
 48
Author: Rohit Jain, 2016-12-20 12:34:55

La raison pour laquelle vous avez du mal à saisir la signification des interfaces fonctionnelles telles que celles de java.util.function est que les interfaces définies ici n'ont aucune signification! Ils sont surtout présents pour représenter structure, pas sémantique.

Ceci est atypique pour la plupart des API Java. L'API Java typique, telle qu'une classe ou une interface, a un sens, et vous pouvez développer un modèle mental pour ce qu'elle représente et l'utiliser pour comprendre les opérations sur elle. Considérer java.util.List par exemple. Un List est un conteneur d'autres objets. Ils ont une séquence et un index. Le nombre d'objets contenus dans la liste retournée par size(). Chaque objet a un index dans la plage 0..taille-1 (inclus). L'objet à l'index , je peut être récupéré par l'appel de list.get(i). Et ainsi de suite.

Les interfaces fonctionnelles dans java.util.function n'ont pas une telle signification. Au lieu de cela, ce sont des interfaces qui représentent simplement la structure d'une fonction, telle que le nombre de arguments, le nombre de valeurs de retour, et (parfois) si un argument ou une valeur de retour est une primitive. Ainsi, nous avons quelque chose comme Function<T,R>, ce qui représente une fonction qui prend un seul argument de type T et renvoie une valeur de type R. C'est tout. Quelle en est la fonction? Eh bien, il ne peut rien faire ... tant qu'il prend un seul argument et renvoie une seule valeur. C'est pourquoi la spécification de Function<T,R> est un peu plus que "Représente une fonction qui en accepte une argument et produit un résultat."

Clairement, quand nous écrivons du code, il a un sens, et ce sens doit venir de quelque part. Dans le cas des interfaces fonctionnelles, la signification vient du contexte dans lequel ils sont utilisés. L'interface Function<T,R> n'a aucune signification isolément. Cependant, dans l'API java.util.Map<K,V>, il y a ce qui suit:

V computeIfAbsent(K key, Function<K,V> mappingFunction)

(caractères génériques élidés pour plus de concision)

Ah, cette utilisation de Function est comme une "fonction de mappage". Ce n'est que faire? Dans ce contexte, si key n'est pas déjà présent dans la carte, la fonction de mappage est appelée et reçoit la clé et devrait produire une valeur, et la paire clé-valeur résultante est insérée dans la carte.

Vous ne pouvez donc pas regarder la spécification de Function (ou l'une des autres interfaces fonctionnelles, d'ailleurs) et tenter de discerner ce qu'elles signifient. Vous devez regarder où ils sont utilisés dans d'autres API pour comprendre ce qu'ils signifient, et cette signification ne s'applique qu'à ce contexte.

 90
Author: Stuart Marks, 2015-02-10 00:54:10

A Supplier est toute méthode qui ne prend aucun argument et renvoie une valeur. Son travail consiste littéralement à fournir une instance d'une classe attendue. Par exemple, chaque référence à une méthode 'getter' est un Supplier

public Integer getCount(){
    return this.count;
}

Sa méthode d'instance de référence myClass::getCount est une instance de Supplier<Integer>.

A Consumer est toute méthode qui prend des arguments et ne renvoie rien. Il est invoqué pour ses effets secondaires. En termes Java, un Consumer est un idiome pour une méthode void. les méthodes' setter ' sont un bon exemple:

public void setCount(int count){
    this.count = count;
}

Sa méthode d'instance de référence myClass::setCount est une instance de Consumer<Integer> et IntConsumer.

Un Function<A,B> est toute méthode qui prend un argument d'un type, et renvoie un autre. Cela peut être appelé une "transformation". Le Function<A,B> prend un A et retourne un B. Remarquable, c'est que pour une valeur donnée de A, la fonction doit toujours retourner une valeur spécifique de B. A et B peuvent en fait être du même type, par exemple:

public Integer addTwo(int i){
    return i+2;
}

Une classe la référence de méthode à un getter est également une fonction.

public Integer getCount(){
    return this.count;
}

Sa méthode de la classe de référence MyClass::getCount est une instance de Function<MyClass,Integer> et ToIntFunction<MyClass>.

 18
Author: Steve K, 2017-09-12 23:11:47

Pourquoi les interfaces fonctionnelles Consommateur/Fournisseur/autre sont-elles définies en java.util.function package : Consumer et Supplier sont deux, parmi d'autres, des interfaces fonctionnelles intégrées fournies dans Java 8. Le but de toutes ces interfaces fonctionnelles intégrées est de fournir un "modèle" prêt pour les interfaces fonctionnelles ayant des descripteurs de fonction communs(signatures/définitions de méthode fonctionnelle).

Disons que nous avons un requis pour convertir un type T en un autre type R. Si nous devions passez toute fonction définie comme ceci en tant que paramètre à une méthode, alors cette méthode devra définir une Interface fonctionnelle dont la méthode fonctionnelle/abstraite prend un paramètre de type T en entrée et donne un paramètre de type R en sortie. Maintenant, il pourrait y avoir de nombreux scénarios comme celui-ci et le ou les programmeurs finiraient par définir plusieurs interfaces fonctionnelles pour leurs besoins. Pour éviter ce genre de scénario, faciliter la programmation et apporter une norme commune dans l'utilisation des interfaces fonctionnelles, un un ensemble d'interfaces fonctionnelles intégrées telles que Prédicat, Fonction, Consommateur et fournisseur ont été définies.

Que fait le consommateur: L'interface fonctionnelle du consommateur accepte une entrée, fait quelque chose avec cette entrée et ne donne aucune sortie. Sa définition est comme ceci (à partir de la source Java) -

@FunctionalInterface
public interface Consumer<T> {
 void accept(T t);
}

Ici accept() est la méthode fonctionnelle\abstract qui prend une entrée et ne renvoie aucune sortie. Donc, si vous voulez entrer un entier, faites quelque chose avec sans sortie ensuite, au lieu de définir votre propre interface, utilisez une instance de Consumer.

Que fait le fournisseur: L'interface fonctionnelle du fournisseur ne prend aucune entrée mais renvoie une sortie. C'est défini comme ceci (à partir de la source Java) -

@FunctionalInterface
public interface Supplier<T> {
  T get();
}

Partout où vous avez besoin d'une fonction qui renvoie quelque chose, disons un entier, mais qui ne prend aucune sortie, utilisez une instance de Fournisseur.

Dans le cas où plus de clarté, avec exemple d'utilisation, des interfaces consommateur et fournisseur est nécessaire, vous pouvez vous référer les articles de mon blog sur le mêmehttp://www.javabrahman.com/java-8/java-8-java-util-function-consumer-tutorial-with-examples/ et http://www.javabrahman.com/java-8/java-8-java-util-function-supplier-tutorial-with-examples/

 7
Author: Dhruv Rai Puri, 2017-03-09 10:37:49

1. Signification

Voir mes réponses à ma question ici et aussi un autre ici, mais en bref, ces nouvelles Interfaces fournissent convention et descriptif pour tout le monde (+ funky chaînage de méthode comme .forEach(someMethod().andThen(otherMethod()))

2. Différences

Consommateur: Prend quelque chose, quelque chose, ne retourne rien: void accept(T t)

Fournisseur: Ne prend rien, renvoie quelque chose : T get() (inverse du consommateur, essentiellement un méthode universelle "getter")

3. Utilisation

// Consumer: It takes something (a String) and does something (prints it) 
    List<Person> personList = getPersons();

     personList.stream()
                    .map(Person::getName)    
                    .forEach(System.out::println); 

Fournisseur: encapsuler le code répétitif, par exemple le calendrier d'exécution du code

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;
    }
}
 6
Author: Andrejs, 2017-05-23 10:31:25

En termes Profanes,

Le fournisseur fournira des données mais sans consommer de données. En termes de programmation, une méthode qui ne prend aucun argument mais renvoie une valeur. Il est utilisé pour générer de nouvelles valeurs.

Http://codedestine.com/java-8-supplier-interface/

Le consommateur consommera des données et ne retournera aucune donnée. En termes de programmation, une méthode qui prend plusieurs arguments et ne renvoie aucune valeur.

Http://codedestine.com/java-8-consumer-interface/

 -1
Author: lalitbhagtani, 2017-02-07 11:47:30

Consommateur et fournisseur sont les interfaces fournies par java. Le consommateur est utilisé pour itérer sur les éléments de la liste et le fournisseur est utilisé pour les objets d'approvisionnement

Vous pouvez facilement comprendre avec la démonstration de code.

Consommateur

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);

    }

}

Fournisseur

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());
    }

}
 -1
Author: Ankit Sood, 2017-04-20 07:21:37