Secuencias de Java para principiantes: Introducción al uso de secuencias en Java
Los flujos de Java 8 permiten a los desarrolladores extraer datos precisos de una gran colección, utilizando un conjunto de operaciones predefinidas.
Antes del lanzamiento de Java 8, el uso del término "flujo" en Java se asociaría automáticamente con E / S. Sin embargo, Java 8 introdujo una secuencia que puede denominarse un conjunto de pasos computacionales encadenados en lo que comúnmente se conoce como una "canalización de secuencias".
Este artículo le presentará los flujos de Java 8 y demostrará cómo pueden ser útiles en sus proyectos.
¿Qué es una corriente?
Una secuencia es una interfaz Java que toma una fuente, realiza un conjunto de operaciones para extraer datos específicos y luego proporciona esos datos a la aplicación para su uso. Básicamente, le permite extraer datos especializados de una colección de datos generalizados.
Cómo funcionan las corrientes
Una canalización de flujo siempre comienza con una fuente. El tipo de fuente depende del tipo de datos con los que está tratando, pero dos de los más populares son las matrices y las colecciones.
Para transformar la colección en una secuencia inicial, deberá agregar la función stream () a la fuente. Esto colocará la fuente en la canalización de flujo donde varias operaciones intermedias diferentes (como filter () y sort () ) pueden operar en ella.
Una vez realizadas todas las operaciones intermedias necesarias, puede introducir una operación de terminal (como forEach () ), que producirá los datos extraídos previamente de la fuente.
Vida sin corrientes
Java 8 se lanzó en 2014, pero antes de eso, los desarrolladores de Java aún necesitaban extraer datos especializados de una colección de datos generales.
Supongamos que tiene una lista de caracteres aleatorios que se combinan con números aleatorios para formar valores de cadena únicos, pero solo desea los valores que comienzan con el carácter "C" y desea organizar el resultado en orden ascendente. Así es como extraerías esos datos sin flujos.
Ejemplo de filtrado y ordenación de valores sin secuencias
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
//declare and initialize the array list
List<String> randomValues = Arrays.asList(
"E11", "D12", "A13", "F14", "C15", "A16",
"B11", "B12", "C13", "B14", "B15", "B16",
"F12", "E13", "C11", "C14", "A15", "C16",
"F11", "C12", "D13", "E14", "D15", "D16"
);
//declare the array list will store needed values
List<String> requiredValues = new ArrayList<>();
//extracting the required values and storing them in reqquiredValues
randomValues.forEach(value -> {
if(value.startsWith("C")) {
requiredValues.add(value);
}
});
//sort the requiredValues in ascending order
requiredValues.sort((String value1, String value2) -> value1.compareTo(value2));
//print each value to the console
requiredValues.forEach((String value) -> System.out.println(value));
}
}
También deberá declarar e inicializar la lista de matrices, ya sea que esté utilizando flujos o algún otro método de extracción. Lo que no necesitaría hacer si estuviera usando flujos es declarar una nueva variable para contener los valores requeridos, ni crear las otras cinco líneas de código en el ejemplo anterior.
El código anterior produce el siguiente resultado en la consola:
C11
C12
C13
C14
C15
C16
Vida con arroyos
En programación, la eficiencia habla de producir el mismo resultado con mucho menos código. Esto es exactamente lo que hace una canalización de flujo para un programador. Entonces, la próxima vez que alguien pregunte: "¿por qué es importante usar transmisiones en su proyecto?" En pocas palabras: "las transmisiones admiten una programación eficiente".
Continuando con nuestro ejemplo anterior, así es como la introducción de transmisiones transforma todo el programa.
Filtrar y ordenar valores con un ejemplo de flujo
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
//declare and initialize the array list
List<String> randomValues = Arrays.asList(
"E11", "D12", "A13", "F14", "C15", "A16",
"B11", "B12", "C13", "B14", "B15", "B16",
"F12", "E13", "C11", "C14", "A15", "C16",
"F11", "C12", "D13", "E14", "D15", "D16"
);
//retrieves only values that start with C, sort them, and print them to the console.
randomValues.stream().filter(value->value.startsWith("C")).sorted().forEach(System.out::println);
}
}
El código anterior demuestra cuán poderosa es la interfaz de transmisión. Toma una lista de valores de matriz aleatorios y la transforma en una secuencia usando la función stream () . Luego, la secuencia se reduce a una lista de matriz que contiene los valores requeridos (que son todos los valores que comienzan con C ), usando la función filter () .
Como puede ver en el ejemplo anterior, los valores de C están ordenados aleatoriamente en la lista de matrices. Si tuviera que imprimir la secuencia en este punto de la canalización, el valor C15 se imprimiría primero. Por lo tanto, la función sort () se introduce en el flujo de flujo para reorganizar la nueva matriz en orden ascendente.
La función final en la canalización de flujo es una función forEach () . Esta es una función de terminal que se usa para detener la canalización de transmisión y produce los siguientes resultados en la consola:
C11
C12
C13
C14
C15
C16
Stream de operaciones intermedias
Existe una lista extensa de operaciones intermedias que se pueden usar en una canalización de flujo.
Una canalización de flujo siempre comienza con una fuente única y una función stream () , y siempre termina con una operación de terminal única (aunque hay varias diferentes para elegir). Pero entre estas dos secciones hay una lista de seis operaciones intermedias que puedes usar.
En nuestro ejemplo anterior, solo se utilizan dos de estas operaciones intermedias — filter () y sort () . La operación intermedia que elija dependerá de las tareas que desee realizar.
Si alguno de los valores que comienzan con "C" en nuestra lista de arreglos anterior estuviera en minúsculas y realizáramos las mismas operaciones intermedias en ellos, obtendríamos el siguiente resultado.
Ejemplo de realización de operaciones de filtrado y ordenación en valores minúsculas
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
//declare and initialize the array list
List<String> randomValues = Arrays.asList(
"E11", "D12", "A13", "F14", "C15", "A16",
"B11", "B12", "c13", "B14", "B15", "B16",
"F12", "E13", "C11", "C14", "A15", "c16",
"F11", "C12", "D13", "E14", "D15", "D16"
);
//retrieves only values that start with C, sort them, and print them to the console.
randomValues.stream().filter(value->value.startsWith("C")).sorted().forEach(System.out::println);
}
}
El código anterior producirá los siguientes valores en la consola:
C11
C12
C14
C15
El único problema con la salida anterior es que no representa con precisión todos los valores de C en nuestra lista de matrices. Una buena forma de corregir este pequeño error es introducir otra operación intermedia en la tubería de flujo; esta operación se conoce como función map () .
Uso del ejemplo de función de mapa
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
//declare and initialize the array list
List<String> randomValues = Arrays.asList(
"E11", "D12", "A13", "F14", "C15", "A16",
"B11", "B12", "c13", "B14", "B15", "B16",
"F12", "E13", "C11", "C14", "A15", "c16",
"F11", "C12", "D13", "E14", "D15", "D16"
);
//transforms all lower case characters to upper case,
//retrieves only values that start with C, sort them, and print them to the console.
randomValues.stream().map(String::toUpperCase).filter(value->value.startsWith("C")).sorted().forEach(System.out::println);
}
}
La función map () transforma un objeto de un estado a otro; en nuestro ejemplo anterior, transforma todos los caracteres en minúsculas de la lista de matrices en caracteres en mayúsculas.
Colocar la función map () justo antes de la función filter () recupera todos los valores que comienzan con C de la lista de matrices.
El código anterior produce el siguiente resultado en la consola, representando con éxito todos los valores de C en la lista de matrices.
C11
C12
C13
C14
C15
C16
Las otras tres operaciones intermedias que puede utilizar en sus aplicaciones incluyen:
- ojeada()
- límite()
- saltar()
Los flujos de Java 8 facilitan la creación de código eficiente
Con los flujos de Java 8, puede extraer datos relevantes adicionales de una fuente grande con una línea de código. Siempre que incluya la función stream () inicial y un operador de terminal, puede utilizar cualquier combinación de operaciones intermedias que proporcionen resultados adecuados para su objetivo.
Si se está preguntando acerca de la línea de código incluida dentro de nuestra función filter () ; se conoce como "expresión lambda". Las expresiones lambda son otra característica introducida con Java 8, y tiene muchas pepitas que pueden resultarle útiles.