Introducido en Java 8, Stream API se usa para procesar colecciones de objetos. Una secuencia es una secuencia de objetos que admite varios métodos que se pueden canalizar para producir el resultado deseado. Antes de continuar, analicemos la diferencia entre Collection y Streams para comprender por qué se introdujo este concepto.
Nota:
- Si queremos representar un grupo de objetos como una sola entidad, debemos ir a la colección .
- Pero si queremos procesar objetos de la colección, deberíamos buscar flujos.
Si queremos usar el concepto de flujos entonces stream() es el método a usar. Stream está disponible como una interfaz.
Stream s = c.stream();
En la etiqueta previa anterior, ‘c’ se refiere a la colección. Entonces, en la colección, llamamos al método stream() y, al mismo tiempo, lo almacenamos como el objeto Stream. De ahora en adelante, de esta manera obtendremos el objeto Stream.
Nota: Los flujos están presentes en el paquete de utilidades de Java llamado java.util.stream
Comencemos ahora con los componentes básicos involucrados en las corrientes. Ellos como se enumeran y como sigue:
- Secuencia de Elementos
- Fuente
- Operaciones Agregadas
- Canalización
- iteración interna
¿Características de la corriente de Java?
- Una secuencia no es una estructura de datos, sino que recibe información de las colecciones, arrays o canales de E/S.
- Los flujos no cambian la estructura de datos original, solo proporcionan el resultado según los métodos canalizados.
- Cada operación intermedia se ejecuta con pereza y devuelve una secuencia como resultado, por lo tanto, se pueden canalizar varias operaciones intermedias. Las operaciones de terminal marcan el final de la secuencia y devuelven el resultado.
Antes de avanzar en el concepto, considere un ejemplo en el que tenemos ArrayList de enteros, y suponemos que aplicamos un filtro para obtener solo números pares del objeto insertado.
¿Cómo funciona Stream internamente?
en arroyos,
- Para filtrar los objetos, tenemos una función llamada filter()
- Para imponer una condición tenemos una lógica de predicado que no es más que una interfaz funcional. Aquí la interfaz de función se puede reemplazar por una expresión aleatoria. Por lo tanto, podemos imponer directamente la condición de verificación en nuestro predicado.
- Para recopilar elementos, utilizaremos Collectors.toList() para recopilar todos los elementos necesarios.
- Por último, almacenaremos estos elementos en una Lista y mostraremos las salidas en la consola.
Ejemplo
Java
// Java Program to illustrate FILTER & COLLECT Operations // Importing input output classes import java.io.*; // Importing utility class for List and ArrayList classes import java.util.*; // Importing stream classes import java.util.stream.*; // Main class public class GFG { // Main driver method public static void main(String[] args) { // Creating an ArrayList object of integer type ArrayList<Integer> al = new ArrayList<Integer>(); // Inserting elements to ArrayList class object // Custom input integer numbers al.add(2); al.add(6); al.add(9); al.add(4); al.add(20); // First lets print the collection System.out.println("Printing the collection : " + al); // Printing new line for better output readability System.out.println(); // Stream operations // 1. Getting the stream from this collection // 2. Filtering out only even elements // 3. Collecting the required elements to List List<Integer> ls = al.stream() .filter(i -> i % 2 == 0) .collect(Collectors.toList()); // Print the collection after stream operation // as stored in List object System.out.println( "Printing the List after stream operation : " + ls); } }
Printing the collection : [2, 6, 9, 4, 20] Printing the List after stream operation : [2, 6, 4, 20]
Explicación de salida: En nuestro objeto de colección, teníamos elementos ingresados usando la operación add(). Después de procesar el objeto en el que se almacenaron a través de flujos, imponemos una condición en el predicado de flujos para obtener solo elementos pares, obtenemos elementos en el objeto según nuestro requisito. Por lo tanto, las secuencias nos ayudaron de esta manera en el procesamiento de objetos de colección sobreprocesados.
¿Varias operaciones centrales sobre Streams?
En términos generales, hay 3 tipos de operaciones que se llevan a cabo en flujos, a saber, como se muestra a continuación en la imagen que se muestra arriba:
- Operaciones intermedias
- Operaciones de terminales
- Operaciones de cortocircuito
Analicemos las operaciones intermedias aquí solo en flujos hasta una cierta profundidad con la ayuda de un ejemplo para descubrir otras operaciones a través de medios teóricos. Entonces, hay 3 tipos de operaciones intermedias que son las siguientes:
- Operación 1: método filter()
- Operación 2: método map()
- Operación 3: método sorted()
Los tres se analizan a continuación, ya que van de la mano en casi la mayoría de los escenarios y para proporcionar una mejor comprensión al usarlos más adelante implementándolos en nuestros programas limpios de Java a continuación. Como ya hemos estudiado en el ejemplo anterior en el que estamos tratando de filtrar los objetos procesados, puede interpretarse como una operación filter() operada sobre flujos. Más tarde, a partir de los elementos filtrados procesados de los objetos, estamos recopilando los elementos nuevamente en la Lista utilizando Collectors para los cuales hemos importado un paquete específico llamado java.util.stream con la ayuda del método Collectors.toList(). Esto se conoce como operación de recopilación() en flujos, por lo que aquí nuevamente no tomaremos un ejemplo para discutirlos por separado.
Ejemplo:
Java
// Java program to illustrate Intermediate Operations // in Streams // Importing required classes import java.io.*; import java.util.*; import java.util.stream.*; // Main class class Test { // Main driver method public static void main(String[] args) { // Creating an integer Arraylist to store marks ArrayList<Integer> marks = new ArrayList<Integer>(); // These are marks of the students // Considering 5 students so input entries marks.add(30); marks.add(78); marks.add(26); marks.add(96); marks.add(79); // Printing the marks of the students before grace System.out.println( "Marks of students before grace : " + marks); // Now we want to grace marks by 6 // using the streams to process over processing // collection // Using stream, we map every object and later // collect to List // and store them List<Integer> updatedMarks = marks.stream() .map(i -> i + 6) .collect(Collectors.toList()); // Printing the marks of the students after grace System.out.println( "Marks of students after grace : " + updatedMarks); } }
Marks of students before grace : [30, 78, 26, 96, 79] Marks of students after grace : [36, 84, 32, 102, 85]
Nota: Para cada objeto, si existe la urgencia de realizar algunas operaciones, ya sea cuadradas, dobles o cualquier otra que no sea solo, necesitamos usar la operación de la función map(); de lo contrario, intente usar la operación de la función filter().
Ahora, geeks, saben muy bien «por qué» se introdujeron las transmisiones, pero deberían preguntarse «dónde» usarlas. La respuesta es muy simple, ya que los usamos con demasiada frecuencia en nuestra vida cotidiana. Por lo tanto, el geek, en palabras más simples, decimos directamente aterrizar en donde sea aplicable el concepto de colección, el concepto de flujos se puede aplicar allí.
Ejemplo de la vida real
Ejemplo 1: en general, en el mundo diario, cada vez que los datos se extraen de la base de datos, es más probable que usemos la recopilación, por lo que el concepto de flujos debe aplicarse para tratar con los datos procesados.
Ahora discutiremos ejemplos en tiempo real para interrelacionar flujos en nuestra vida. Aquí tomaremos los más utilizados, a saber, los siguientes:
- Arroyos en una tienda de comestibles
- Flujos en redes móviles
Ejemplo 2: Transmisiones en una tienda de comestibles
La imagen pictórica anterior se ha proporcionado y se implementa en secuencias, que es la siguiente:
List<Integer> transactionsIds = transactions.stream() .filter(t -> t.getType() == Transaction.GROCERY) .sorted(comparing(Transaction::getValue).reversed()) .map(Transaction::getId) .collect(toList());
Ejemplo 3: Streams en redes móviles
Del mismo modo, podemos optar por otro concepto muy utilizado que es el trato con nuestros números de móvil. Aquí no propondremos listados, simplemente demostraremos cómo varios proveedores de servicios en todo el mundo invocan el concepto de flujo en las redes móviles.
La colección puede contener cualquier cantidad de objetos, así que deje que ‘mobileNumber’ sea una colección y que contenga varios números móviles, digamos que contiene más de 100 números como objetos. Supongamos ahora que el único operador llamado ‘Airtel’ con el que se supone que debemos enviar un mensaje si hay alguna migración entre estados en un país. Así que aquí el concepto de flujos se aplica como si al tratar con todos los números móviles buscáramos este operador utilizando la operación del método filter() de flujos. De esta manera, podemos entregar los mensajes sin tener que buscar todos los números móviles y luego entregar el mensaje, lo que parece poco práctico si se hace así, ya que ya es demasiado tarde para entregar. De esta manera, estas operaciones intermedias, a saber, filter(), collect(), map() ayudan en el mundo real.
Espero que ahora los usuarios se den cuenta del poder de las secuencias en Java, ya que si tuviéramos que hacer la misma tarea, necesitamos mapear correspondiente a cada objeto, aumentando la longitud del código, disminuyendo la optimización de nuestro código. Con el uso de flujos, podemos en una sola línea, independientemente de los elementos contenidos en el objeto, ya que con el concepto de flujos estamos tratando con el objeto mismo.
Nota: filtrar, ordenar y mapear, que se pueden conectar entre sí para formar una canalización.
Publicación traducida automáticamente
Artículo escrito por solankimayank y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA