12 formas comunes de utilizar Java Streams
Fuente: Dev.to La API Java Streams apareció por primera vez en Java 8. Su propósito es proporcionar una forma más compacta de realizar operaciones comunes en colecciones de objetos. Además, la API Java Streams se puede utilizar para implementar algoritmos complejos. En este artículo, hablaremos sobre casos de uso comunes de Java Streams. Primero, aclaremos algunos conceptos básicos:-
stream() : crea una secuencia a partir de la colección.
-
Collect() : recopila una secuencia en un objeto. Un objeto puede ser una colección, una primitiva o una clase personalizada.
-
Collectors es una clase que proporciona (muchos) métodos estáticos para recopilar transmisiones.
1. Filtrado
-
Se utiliza para eliminar valores de una Colección según una condición.
-
Para filtrar elementos de la colección según una condición, utilice el método filter() . Sólo se guardan los elementos coincidentes.
List<Integer> evenNumbers = originalList.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
2. Preprocesamiento
-
Útil cuando es necesario cambiar todos los valores de una colección.
-
El método map() se utiliza para aplicar una función a cada elemento de la colección y devolver una nueva colección de valores calculados.
List<Integer> squares = originalList.stream()
.map(n -> n * n)
.collect(Collectors.toList());
3. Conversión
-
Útil cuando queremos transformar una colección en otra colección.
-
Hay varias formas de lograrlo.
Ejemplo 1: crear un mapa a partir de listas.
Convierta una lista de cadenas en un mapa de cadenas y longitudes.Map<String, Integer> wordLengths = words.stream()
.collect(Collectors.toMap(
word -> word,
word -> word.length()));
Ejemplo 2. Convertir una lista en conjuntos.
Este es un caso de uso común para eliminar duplicados. Además, si queremos volver a colocar elementos en la lista, podemos usar los métodos stream() y Collect() dos veces . Por ejemplo, conviertamos una lista de cadenas en una lista de cadenas únicas:// if we want to collect to a set
Set<String> uniqueWords = words.stream()
.collect(Collectors.toSet());
// OR
// if we want to start and end as a list
List<String> uniqueWords = words.stream()
.collect(Collectors.toSet()).stream().collect(Collectors.toList());
Ejemplo 3. Convertir una lista de productos en una lista de sus nombres. (Aplanamiento - Alineación)
List<String> productNames = products.stream()
.map(product -> product.getName())
.collect(Collectors.toList());
4. Reducción
-
Reduce la colección a un solo valor.
-
El método reduce() se utiliza para aplicar una función a cada elemento de la colección y devolver un valor único.
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
5. Agrupación
-
Agrupa los elementos de una Colección según una condición determinada.
-
Para agrupar elementos de la Colección por condición, utilice el método Collectors.groupingBy() .
Map<String, List<Product>> productsByCategory = products.stream()
.collect(Collectors.groupingBy(product -> product.getCategory()));
6. Encontrar
-
Busca el primer elemento de la Colección o cualquier elemento que coincida con una condición.
-
Los métodos findFirst() y findAny() se utilizan para realizar búsquedas .
Optional<String> firstLongWord = words.stream()
.filter(word -> word.length() > 5)
.findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.
7. Clasificación
-
Ordena los elementos de Colecciones.
-
El método sorted() se utiliza para ordenar .
List<Integer> topK = numbers.stream()
.sorted()
.limit(k)
.collect(Collectors.toList());
8. Partición
-
Separa los elementos de una Colección en función de una condición determinada.
-
El método Collectors.partitioningBy() se utiliza para separar elementos .
Map<Boolean, List<Student>> passingFailing = students
.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
9. Contando
-
Cuenta el número de elementos que coinciden con una condición.
-
El método count() se utiliza para contar el número de elementos que coinciden con una condición .
long count = words.stream()
.filter(word -> word.length() > 5)
.count();
10. rango
-
Crea un rango de valores.
-
Para crear un rango de valores, utilice el método range() .
int[] numbers = IntStream.range(0, 10).toArray();
11. Coincidencia
-
Relaciona los elementos de una colección con un predicado (condición).
-
Métodos como anyMatch() , allMatch() y noneMatch() se utilizan para hacer coincidir elementos de la colección con un predicado y devolver un valor booleano .
// true when all elements match the predicate
boolean allMatch = products.stream()
.allMatch(product -> product.getPrice() > 10);
// true when any element matches the predicate
boolean anyMatch = products.stream()
.anyMatch(product -> product.getPrice() > 10);
// true when no elements match the predicate
boolean noneMatch = products.stream()
.noneMatch(product -> product.getPrice() > 10);
12. Unirse
-
Concatena los elementos de una colección en una cadena.
-
Para unir elementos de la colección en una cadena, utilice el método Collectors.joining() .
String joinedWords = words.stream()
.collect(Collectors.joining(" "));
Eso es todo para escenarios generales. Hay otros escenarios menos comunes que puedes explorar por tu cuenta:
- Corrientes paralelas;
- Estadísticas;
- Coleccionistas personalizados.
Beneficios de los hilos
-
Código más compacto: reduce la cantidad de código necesario para procesar la colección.
-
Menos variables intermedias. Las variables que intervienen pueden provocar que se produzcan errores. Cuantos menos sean, más fácil será evitar errores inesperados.
-
Código intuitivo. Algunos desarrolladores no estarán de acuerdo con que los subprocesos sean más intuitivos que otros métodos. Sin embargo, una vez que nos acostumbramos a ellos, se vuelven mucho más intuitivos que otros métodos.
Cómo evaluar la asignación de memoria de un objeto en Java
Fuente: DZone Este artículo muestra las tres formas más conocidas de evaluar la asignación de memoria de un objeto en Java.Evaluación de la memoria usando Profiler
La forma más sencilla de estimar la memoria de algunos objetos es buscar directamente en la memoria JVM utilizando un generador de perfiles como Visual VM . El problema con este enfoque es que necesita conectarse a una JVM en ejecución, lo que puede no ser posible en entornos de producción por razones de seguridad.Evaluación de la memoria mediante instrumentos.
Otra forma de estimar la memoria asignada para un objeto determinado es utilizar Instrumentos. En términos simples, necesitamos crear una clase y compilarla en un JAR. Después de crear el JAR, debemos ejecutar nuestra JVM junto con ese JAR. Puedes encontrar más información sobre este método aquí . La desventaja aquí es la necesidad de agregar un archivo jar específico a la JVM, que puede no ser aceptable para producción debido a problemas de seguridad o relacionados.Evaluación de la memoria utilizando la biblioteca JOL
Como otra opción, podemos utilizar JOL Library . Esta es una biblioteca muy poderosa que puede proporcionar una estimación detallada del peso de un objeto y la memoria asignada por una instancia de objeto. Para usar la biblioteca, necesitamos agregar una dependencia:<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.16</version>
</dependency>
Después de eso podemos usarlo así:
out.println(GraphLayout.parseInstance(myObject).totalSize() / 1024000d + " MB")
ObjectSizeCalculator del archivo de Twitter
El repositorio público de GitHub de Twitter tiene una clase de herramienta llamada ObjectSizeCalculator que puede estimar la memoria asignada para una instancia de objeto determinada. No requiere mucha memoria ni tiempo para su uso. El proceso de evaluación dura unos segundos, incluso para objetos grandes. Usar esta clase es bastante simple:ObjectSizeCalculator.getObjectSize(address)
Recomiendo este método, pero tenga en cuenta que sólo es compatible con Java Hotspot, OpenJDK y TwitterJDK.
GO TO FULL VERSION