jdk descargar java java-8

java - descargar - jdk 11



Java 8 Proveedor y consumidor explicación para el laico (7)

Como programador no Java que aprende Java, en este momento estoy leyendo sobre las interfaces de Supplier y Consumer . Y no puedo entender mi uso y significado. ¿Cuándo y por qué usarías estas interfaces? ¿Puede alguien darme un ejemplo laico simple de esto ... Estoy encontrando que los ejemplos de Doc no son lo suficientemente sucintos para mi comprensión.


1. Significado

Vea mis respuestas a mi pregunta here y también otra here , pero en resumen, estas nuevas interfaces proporcionan convenciones y descripciones para que todos las usen (+ encadenamiento de métodos funky como .forEach(someMethod().andThen(otherMethod()))

2. diferencias

Consumidor : Toma algo, hace algo, no devuelve nada: void accept(T t)

Proveedor: no toma nada, devuelve algo: T get() (reverso del consumidor, básicamente un método universal ''getter'')

3. Uso

// Consumer: It takes something (a String) and does something (prints it) List<Person> personList = getPersons(); personList.stream() .map(Person::getName) .forEach(System.out::println);

Proveedor: envolver código repetitivo, por ejemplo, tiempo de ejecución de código

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


¡La razón por la que tiene dificultades para comprender el significado de las interfaces funcionales como las de java.util.function es que las interfaces definidas aquí no tienen ningún significado! Están presentes principalmente para representar la estructura , no la semántica .

Esto es atípico para la mayoría de las API de Java. La API Java típica, como una clase o interfaz, tiene significado, y puede desarrollar un modelo mental para lo que representa y usarlo para comprender las operaciones en él. Considere java.util.List por ejemplo. Una List es un contenedor de otros objetos. Tienen una secuencia y un índice. El número de objetos contenidos en la lista es devuelto por size() . Cada objeto tiene un índice en el rango 0..size-1 (inclusive). El objeto en el índice i se puede recuperar llamando a list.get(i) . Etcétera.

Las interfaces funcionales en java.util.function no tienen tal significado. En cambio, son interfaces que simplemente representan la estructura de una función, como el número de argumentos, el número de valores de retorno y (a veces) si un argumento o valor de retorno es primitivo. Por lo tanto, tenemos algo como Function<T,R> que representa una función que toma un solo argumento de tipo T y devuelve un valor de tipo R. Eso es. ¿Qué hace esa función? Bueno, puede hacer cualquier cosa ... siempre que tome un solo argumento y devuelva un solo valor. Es por eso que la especificación para la Function<T,R> es poco más que "Representa una función que acepta un argumento y produce un resultado".

Claramente, cuando estamos escribiendo código, tiene significado, y ese significado tiene que venir de algún lado. En el caso de las interfaces funcionales, el significado proviene del contexto en el que se utilizan. La interfaz Function<T,R> no tiene significado de forma aislada. Sin embargo, en la API java.util.Map<K,V> , existe lo siguiente:

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

(comodines eliminados por brevedad)

Ah, este uso de Function es como una "función de mapeo". Que hace eso En este contexto, si la key no está presente en el mapa, se llama a la función de mapeo y se le entrega la clave y se espera que produzca un valor, y el par clave-valor resultante se inserta en el mapa.

Por lo tanto, no puede mirar la especificación de Function (o cualquiera de las otras interfaces funcionales, para el caso) e intentar discernir lo que significan. Debe ver dónde se usan en otras API para comprender lo que significan, y ese significado se aplica solo a ese contexto.


El consumidor y el proveedor son las interfaces proporcionadas por java. El consumidor se usa para iterar sobre los elementos de la lista y el proveedor se usa para los objetos de suministro

Puedes entenderlo fácilmente con la demostración de código.

Consumidor

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

Proveedor

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



Este es el proveedor:

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

Este es el consumidor:

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

Entonces, en términos simples, un proveedor es un método que devuelve algún valor (como en su valor de retorno). Mientras que, un consumidor es un método que consume algún valor (como en el argumento del método), y realiza algunas operaciones en ellos.

Esos se transformarán en algo como esto:

// 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 cuanto al uso, el ejemplo más básico sería: Stream#forEach(Consumer) . Se necesita un consumidor, que consume el elemento de la secuencia en la que está iterando, y realiza alguna acción en cada uno de ellos. Probablemente imprimirlos.

Consumer<String> stringConsumer = (s) -> System.out.println(s.length()); Arrays.asList("ab", "abc", "a", "abcd").stream().forEach(stringConsumer);


Un Supplier es cualquier método que no toma argumentos y devuelve un valor. Su trabajo es literalmente proporcionar una instancia de una clase esperada. Por ejemplo, cada referencia a un método ''getter'' es un Supplier

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

Su referencia de método de instancia myClass::getCount es una instancia de Supplier<Integer> .

Un Consumer es cualquier método que toma argumentos y no devuelve nada. Se invoca por sus efectos secundarios. En términos de Java, un Consumer es un modismo para un método void . Los métodos ''setter'' son un buen ejemplo:

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

Su referencia de método de instancia myClass::setCount es una instancia de Consumer<Integer> e IntConsumer .

Una Function<A,B> es cualquier método que toma un argumento de un tipo y devuelve otro. Esto puede ser referido como una ''transformación''. La Function<A,B> toma una A y devuelve una B Es notable que para un valor dado de A , la función siempre debe devolver un valor específico de B A y B pueden ser del mismo tipo, como los siguientes:

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

Su método de instancia hace referencia a myClass:addTwo es una Function<Integer, Integer> y una ToIntFunction<Integer> .

Una referencia de método de clase a un captador es otro ejemplo de una función.

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

Su referencia de método de clase MyClass::getCount es una instancia de Function<MyClass,Integer> y ToIntFunction<MyClass> .


¿Por qué se definen las interfaces funcionales Consumer / Supplier / other en el paquete java.util.function ? Consumer y Supplier son dos, entre muchas, de las interfaces funcionales incorporadas proporcionadas en Java 8. El propósito de todas estas interfaces funcionales incorporadas es para proporcionar una "plantilla" lista para interfaces funcionales que tengan descriptores de funciones comunes (firmas / definiciones de métodos funcionales).

Digamos que tenemos que convertir un tipo T a otro tipo R. Si tuviéramos que pasar cualquier función definida como este a un método, entonces ese método necesitaría definir una interfaz funcional cuyo método funcional / abstracto toma parámetro de tipo T como entrada y proporciona un parámetro de tipo R como salida. Ahora, podría haber muchos escenarios como este y los programadores terminarían definiendo múltiples interfaces funcionales para sus necesidades. Para evitar este tipo de escenario, facilite la programación y traiga un estándar común en el uso de interfaces funcionales, se ha definido un conjunto de interfaces funcionales incorporadas como Predicate, Function, Consumer & Supplier.

Qué hace el consumidor : la interfaz funcional del consumidor acepta una entrada, hace algo con esa entrada y no da ninguna salida. Su definición es así (de Java Source):

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

Aquí accept () es el método funcional / abstracto que toma una entrada y no devuelve ninguna salida. Entonces, si desea ingresar un número entero, haga algo con él sin salida y, en lugar de definir su propia interfaz, use una instancia de consumidor.

Qué hace el proveedor : la interfaz funcional del proveedor no toma ninguna entrada pero devuelve una salida. Se define así (desde Java Source):

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

Donde sea que necesite una función que devuelva algo, digamos un número entero, pero no tiene salida, use una instancia de Proveedor.

En caso de que se necesite más claridad, junto con el uso de ejemplo, de las interfaces de Consumidor y Proveedor, puede consultar las publicaciones de mi blog en el mismo: http://www.javabrahman.com/java-8/java-8-java-util-function-consumer-tutorial-with-examples/ y http://www.javabrahman.com/java-8/java-8-java-util-function-supplier-tutorial-with-examples/