Java avanzado: flujo de flujo, referencia de método

1. Transmitir

1.Stream resuelve las deficiencias de las bibliotecas de clases de colección

En Java 8, gracias a la programación funcional aportada por Lambda, se introduce un nuevo concepto Stream para resolver las deficiencias existentes de las bibliotecas de clases de colección existentes.

Casi todas las colecciones (como la interfaz de colección o la interfaz de mapa, etc.) admiten operaciones transversales directas o indirectas. Cuando necesitamos operar sobre los elementos de la colección, además de las adiciones, eliminaciones y adquisiciones necesarias, la más típica es el recorrido de la colección.

Desventajas del recorrido del bucle:

Java8中的Lambda让我们可以更加专注于做什么(What),而不是怎么做(How),此前已经结合内部类进行了对比说明。

对于采用for循环遍历集合的代码,可以分析:

    for循环的语法就是“怎么做”
    
    for循环的循环体就是“做什么”

El propósito de utilizar bucles es atravesar, pero los bucles no son la única forma de atravesar.
Transversal significa que cada elemento se procesa uno por uno, en lugar de un bucle que lo procesa secuencialmente desde el primero hasta el último.
El primero es el propósito, el segundo es el método.

Ejemplo: utilice el método tradicional para recorrer la colección y filtrar los datos de la colección.

过程分析:
    一共使用了3个循环,作用分别为:
        1.首先筛选所有姓张的人
        2.然后筛选名字有三个字的人
        3.最后进行对结果进行打印输出
        
弊端分析:

    每当我们需要对集合中的元素进行操作的时候,总是需要进行循环、循环、再循环。这并不是唯一的方法。
    
    循环是做事情的方式,并不是目的。另一方面,使用线性循环意味着只能遍历一次。如果希望多次遍历, 只能在使用另一个循环从头开始。
    
解决方法:
    使用Lambda的衍生物Stream,优化代码

2. Pensamiento fluido

Utilice el método Stream para recorrer la colección y filtrar los datos de la colección.

Stream Stream apareció después de JDK1.8 y se centra en qué hacer en lugar de cómo hacerlo.

流式思想:

    原理和传统IO流有所不同,整体来看,流式思想类似于工厂车间的“生产流水线”,
    当需要对多个元素进行操作(特别是多步操作)的时候,考虑到性能及便利性,
    我们应该首先拼接好一个 “模型”步骤方案,然后再按照方案去执行它。

3. modelo de flujo

Para las colecciones de listas, existen operaciones de varios pasos, como filtrar, filtrar e imprimir. Esta es una solución para procesar elementos de la colección, y la solución es un "modelo de función". Llamar al método especificado puede convertir de un [modelo de flujo] a otro modelo de flujo.

Hay un método [filtro] en el método de transmisión. El parámetro del método de filtro es la interfaz Predicate, que es una interfaz funcional que puede pasar expresiones Lambda.

Hay un método [forEach] en el método de transmisión, cuyo parámetro es la interfaz del consumidor, que es una interfaz funcional que puede pasar expresiones Lambda.

El filtro y el filtro aquí operan en el modelo de función y los elementos de la colección [en realidad no se procesan]. Solo cuando se ejecute el método final (impresión), todo el modelo realizará operaciones de acuerdo con la estrategia especificada. Esto se debe a la característica [ejecución retrasada] de Lambda, es decir, se ejecutará solo si se cumplen las condiciones y no se ejecutará si no se cumplen las condiciones.

Precauciones:

“Stream流”其实是一个集合元素的函数模型,它并不是集合,也不是数据结构,其本身并不存储
任何元素(或其地址值)

Un Stream es una cola de elementos de una fuente de datos:

1.元素是特定类型(例如String)的对象,形成一个队列(filter、filter、soutp排成一个队列)。
Java中的Stream并不会存储元素(例如第一个filter,并没有真正筛选出姓张的元素),
而是按需计算。

2.数据源:流的来源。可以是集合,数组等。

A diferencia de Collection, la operación Stream también tiene dos características básicas:

1.Pipelining:中间操作都会返回流对象本身。这样多个操作可以串联成一个管道,如同流式
风格(fluent style)。这样做可以对操作进行优化,比如延迟执行(laziness)和短路(short-circuiting)。

2.内部迭代:以前对集合遍历都是通过Iterator或者增强for的方式,显示的在集合外部进行迭代,
叫做外部迭代(即先有集合,在创建迭代器进行遍历)。Stream提供了内部迭代的方式,流可以
直接调用遍历方法(即stream.forEach)。

Cuando se utiliza una transmisión, normalmente hay tres pasos básicos:

获取一个数据源(source)-> 数据转换 -> 执行操作获取想要的结果。

每次转换原有Stream对象不改变,返回一个新的Stream对象(可以有多次转换),
这就允许对其操作可以像链条一样排列,变成一个管道。

4. Dos formas de obtener Stream Stream

Java.util.stream.Stream es la interfaz de transmisión más utilizada recientemente agregada a Java8. (Esta no es una interfaz funcional porque hay más de un método abstracto)

Obtener una transmisión es muy simple y existen varias formas comunes:

1.所有的Collection集合(单列集合)都可以通过stream默认方法获取流

    default Stream<E> stream()
    
2.Stream接口的静态方法of可以获取数组对应的流

    static <T> Stream<T> of (T... values)
    
    参数是一个可变参数,那么就可以传递一个数组(可变参数底层就是一个数组)

Precauciones:

Collection集合可以【直接转换】为Stream流,

Map集合可以【间接先转换】为Collection集合或者Set集合,在转换为Stream流。

对于数组,可以使用Stream接口的【静态方法】of

5.Métodos comunes en Stream

Los métodos comúnmente utilizados en modelos de flujo se pueden dividir en dos tipos:

1.延迟方法:返回值类型仍然是Stream接口自身类型的方法,因此支持链式调用。(除了终结方法外,
其余方法均为延迟方法)

2.终结方法:返回值类型不再是Stream接口自身类型的方法,因此不再支持类似StringBuilder那样的
链式调用

Los flujos de corriente son flujos de tubería y solo se pueden usar (consumir) una vez:

第一个Stream流调用完毕方法,数据就会流转到下一个Stream流上

而这时第一个Stream流已经使用完毕,就会关闭了

所以第一个Stream流就不能再调用方法

5.1 para cada uno

Método en Stream - forEach: se utiliza para recorrer los datos en el flujo

void forEach(Consumer<? super T> action);

Este método recibe una función de interfaz de consumidor y entrega cada elemento de flujo a la función para su procesamiento.
La interfaz del consumidor es una interfaz funcional [del consumidor], por lo que puede pasar expresiones Lambda y consumir datos.

Simplemente recuerda:

forEach方法,用来遍历流中的数据

Es un [método terminador] Después de atravesarlo, no puede continuar llamando a otros métodos en el Stream.

5.2 filtro

Método en Stream - filtro: se utiliza para filtrar datos en Stream

Stream<T> filter(Predicate<? super T> predicate);

filter方法的参数Predicate是一个函数式接口,所以可以传递Lambda表达式,对数据进行过滤

Métodos abstractos en Predicado:

boolean test(T t);

5.3 mapa

Si necesita asignar elementos de una secuencia a otra secuencia, puede utilizar el método de mapa.

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

Esta interfaz requiere un parámetro de interfaz funcional de Función, que puede convertir datos de tipo T en la secuencia actual en otra secuencia de tipo R.

Métodos abstractos en función:

R apply(T t);
这可以将一种T类型转换成为R类型,而这种转换的动作,就称为“映射”。

5.4 cuenta

Método en Stream - count: al igual que el método de tamaño en la antigua Colección, el método count se utiliza para contar el número de elementos en la secuencia.

long count();

El valor de retorno de este método es de tipo largo, no del tipo int de la colección anterior.

El método de conteo es un [método final], por lo que no puede continuar llamando a otros métodos en la secuencia.

límite 5.5

Método en Stream stream - límite: puedes interceptar el stream y solo usar los primeros n

Stream<T> limit(long maxSize);
参数是一个long型,如果集合当前长度大于参数则进行截取;否则不进行操作。

El método de límite es un [método de retraso], que solo intercepta elementos en la secuencia y devuelve una nueva secuencia, por lo que puede continuar llamando a otros métodos en la secuencia.

5.6 saltar

Método en Stream - skip: si desea omitir los primeros elementos, puede usar el método skip para obtener una nueva secuencia después de la interceptación.

Stream<T> skip(long n);
如果流的当前长度大于n,则跳过前n个;否则将会得到一个长度为0的空流。

5.7 concatenación

Método en la secuencia Stream - concat: si hay dos transmisiones y desea fusionarlas en una sola, puede usar el método estático concat de la interfaz Stream.

static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)

Este es un método estático, que es diferente del método concat en java.lang.String.

2. Referencia del método

1.Doble colon::

El método de escritura de dos puntos :: se llama "referencia de método", los dos puntos dobles son una nueva sintaxis, llamada operador de referencia, y la expresión en la que se encuentra se llama "referencia de método".

Si el esquema de función que Lambda expresará ya existe en la implementación de un método, entonces se puede hacer referencia al método mediante dos puntos dobles como reemplazo de Lambda.

Lambda表达式写法:s->System.out.println(s);

方法引用写法:System.out ::println

以上两种写法是等效的,但又有所区别:

    1.第一种的语义是指,拿到参数之后经Lambda之手,继而传递给System.out.println方法去处理
    
    2.第二种的语义是指,直接让System.out中的方法println方法来取代Lambda。
    
    两种写法的执行效果一样,但第二种方法引用的写法复用了已有方案,更加简洁。

注:Lambda中传递的参数一定是方法引用中的那个方法可以接收的类型,否则会抛出异常

2. Hacer referencia a métodos de miembros a través de nombres de objetos.

Requisitos previos para su uso:

1.对象名是已经存在的

2.成员方法时已经存在的

Ejemplo de código:

printString((String s)->{
            System.out.println(s);
        });

/*
 分析:
     Lambda表达式的目的:打印参数传递的字符串
     把参数s,传递给了System.out对象,调用out对象中的方法println,对字符串进行了输出
     注意:
         1.System.out对象是【已经存在】的
         2.println方法也是【已经存在】的
     所以可以使用【方法引用】来优化Lambda表达式,即使用方法引用的前提:方法或对象已经存在
     可以使用System.out方法直接引用(调用)println方法
*/
printString(System.out ::println);  //对象引用方法,双冒号::为引用运算符。

3. Hacer referencia a métodos de miembros estáticos a través de nombres de clases.

Requisitos previos para su uso:

1.类已经存在

2.静态成员方法也已经存在

4. Utilice super para hacer referencia a métodos miembro de la clase principal.

Requisitos previos para su uso:

1.super是已经存在的,super代表父类对象

2.父类的成员方法是已经存在的

所以,可以使用super来引用父类的成员方法

5. Haga referencia a los métodos miembros de esta clase a través de este

Utilice referencias de métodos para optimizar expresiones Lambda, requisitos previos:

1.this是已经存在的,this指代当前对象

2.本类的成员方法也是存在的

所以,可以直接使用this引用本类的成员方法

6. Referencia del constructor de clases (constructor)

Hacer referencia a nuevo a través del constructor, es decir, llamar a su constructor parametrizado a través de la clase.

Requisitos previos para utilizar referencias de métodos para optimizar expresiones Lambda:

1.构造方法new Person(String name)是已知的

2.创建对象是已知的:new

所以就可以使用Person引用new创建对象,实际上就是Person类调用其带参构造方法,
通过传递的姓名创建对象。

7. Referencia del constructor de matrices

Referencia nueva a través de una matriz.

Requisitos previos para utilizar referencias de métodos para optimizar expresiones Lambda:

1.已知创建的就是int[]数组

2.数组的长度也是已知的

所以,可以使用方法引用:int[]引用new,根据参数传递的长度来创建数组

Supongo que te gusta

Origin blog.csdn.net/weixin_42214237/article/details/122847974
Recomendado
Clasificación