encontrar elemento
Ahora estamos familiarizados con este método elegantemente diseñado para transformar colecciones, pero es inútil para encontrar elementos. Pero el método de filtrado nació para esto.
Ahora queremos eliminar los nombres que comienzan con N de una lista de nombres. Por supuesto, puede que no haya ninguno y el resultado puede ser un conjunto vacío. Implementémoslo primero usando el método anterior.
Copie el código de código de la siguiente manera:
Lista final<Cadena> comienza conN = nueva ArrayList<Cadena>();
para (nombre de cadena: amigos) {
if(nombre.startsWith("N")) {
comienzaConN.add(nombre);
}
}
Escribir tanto código para un evento tan simple es bastante detallado. Primero creamos una variable y luego la inicializamos en una colección vacía. Luego recorra la colección original y busque los nombres que comiencen con la letra especificada. Si se encuentra, se inserta en la colección.
Usemos el método de filtro para reconstruir el código anterior y ver qué tan poderoso es.
Copie el código de código de la siguiente manera:
Lista final<Cadena> comienza conN =
amigos.stream()
.filtro(nombre -> nombre.startsWith("N"))
.collect(Collectors.toList());
El método de filtro recibe una expresión lambda que devuelve un valor booleano. Si la expresión se evalúa como verdadera, ese elemento en el contexto de ejecución se agrega al conjunto de resultados; de lo contrario, se omite; Lo que finalmente se devuelve es Steam, que contiene solo aquellos elementos cuya expresión devuelve verdadero. Finalmente, utilizamos un método de recopilación para convertir la colección en una lista; analizaremos este método con más profundidad en Uso del método de recopilación y la clase Collecters en la página 52.
Imprimamos los elementos en este conjunto de resultados:
Copie el código de código de la siguiente manera:
System.out.println(String.format("%d nombres encontrados", comienza conN.size()));
Del resultado se desprende claramente que este método ha encontrado todos los elementos coincidentes en la colección.
Copie el código de código de la siguiente manera:
Encontré 2 nombres
El método de filtro, al igual que el método de mapa, también devuelve un iterador, pero eso es todo. La colección devuelta por el mapa tiene el mismo tamaño que la colección de entrada, pero es difícil decir qué devuelve el filtro. El rango de tamaño del conjunto que devuelve, desde 0 hasta el número de elementos del conjunto de entrada. A diferencia del mapa, el filtro devuelve un subconjunto del conjunto de entrada.
Hasta ahora, estamos muy satisfechos con la simplicidad del código que aportan las expresiones lambda, pero si no tenemos cuidado, el problema de la redundancia del código comenzará a crecer lentamente. Analicemos este tema a continuación.
Reutilización de expresiones lambda
Las expresiones lambda parecen muy concisas, pero de hecho es fácil hacer que el código sea redundante si no se tiene cuidado. La redundancia provocará una baja calidad del código y dificultades de mantenimiento; si queremos realizar un cambio, tendremos que cambiar varios códigos relacionados juntos.
Evitar la redundancia también puede ayudarnos a mejorar el rendimiento. El código relevante se concentra en un solo lugar, de modo que podamos analizar su rendimiento y luego optimizar el código aquí, lo que puede mejorar fácilmente el rendimiento del código.
Ahora echemos un vistazo a por qué el uso de expresiones lambda puede conducir fácilmente a la redundancia de código y consideremos cómo evitarla.
Copie el código de código de la siguiente manera:
Lista final<String> amigos =
Arrays.asList("Brian", "Nate", "Neal", "Raju", "Sara", "Scott");
editores finales de Lista<Cadena> =
Arrays.asList("Brian", "Jackie", "John", "Mike");
Lista final<String> camaradas =
Arrays.asList("Kate", "Ken", "Nick", "Paula", "Zach");
Queremos filtrar los nombres que comienzan con una letra determinada.
Queremos filtrar nombres que comiencen con una letra determinada. Simplemente implementémoslo usando el método de filtro primero.
Copie el código de código de la siguiente manera:
cuenta larga finalFriendsStartN =
amigos.stream()
.filter(nombre -> nombre.startsWith("N")).count();
cuenta larga finalEditorsStartN =
editores.stream()
.filter(nombre -> nombre.startsWith("N")).count();
cuenta larga finalCamradesStartN =
camaradas.stream()
.filter(nombre -> nombre.startsWith("N")).count();
Las expresiones lambda hacen que el código parezca conciso, pero, sin saberlo, aportan redundancia al código. En el ejemplo anterior, si queremos cambiar la expresión lambda, tenemos que cambiar más de un lugar, lo cual no es posible. Afortunadamente, podemos asignar expresiones lambda a variables y reutilizarlas como objetos.
El método de filtro, el receptor de la expresión lambda, recibe una referencia a la interfaz funcional java.util.function.Predicate. Aquí, el compilador de Java vuelve a ser útil. Genera una implementación del método de prueba de Predicate utilizando la expresión lambda especificada. Ahora podemos pedirle más explícitamente al compilador de Java que genere este método en lugar de generarlo donde se definen los parámetros. En el ejemplo anterior, podemos almacenar explícitamente la expresión lambda en una referencia de tipo Predicado y luego pasar esta referencia al método de filtro, lo que puede evitar fácilmente la redundancia de código.
Refactoricemos el código anterior para que cumpla con el principio DRY. (No repita el principio - DRY -, consulte el libro The Pragmatic Programmer: From Journeyman to Master [HT00]).
Copie el código de código de la siguiente manera:
Predicado final<Cadena> comienzaConN = nombre -> nombre.startsWith("N");
cuenta larga finalFriendsStartN =
amigos.stream()
.filtro(empiezaConN)
.contar();
cuenta larga finalEditorsStartN =
editores.stream()
.filtro(empiezaConN)
.contar();
cuenta larga finalCamradesStartN =
camaradas.stream()
.filtro(empiezaConN)
.contar();
Ahora, en lugar de volver a escribir la expresión lambda, la escribimos una vez y la almacenamos en una referencia de tipo Predicado llamada comienzaConN. En las siguientes tres llamadas de filtro, el compilador de Java vio la expresión lambda disfrazada de Predicado, sonrió y la aceptó en silencio.
Esta variable recién introducida nos elimina la redundancia de código. Pero desafortunadamente, como veremos más adelante, el enemigo pronto regresará para vengarse. Veamos qué armas más poderosas pueden destruirlos por nosotros.