Dominando las Operaciones Intermedias y Terminales de Java Stream API
Clasificado en Informática
Escrito el en
español con un tamaño de 4,41 KB
Referencia de Operaciones de la API Stream de Java
La API Stream de Java facilita el procesamiento funcional de colecciones de datos. Sus operaciones se dividen en dos categorías principales: intermedias y terminales.
Operaciones Intermedias
Las operaciones intermedias devuelven un nuevo Stream, permitiendo encadenar múltiples operaciones. Son de ejecución perezosa (lazy).
distinct- Devuelve un stream con los elementos distintos.
filter- Devuelve un stream con los elementos que cumplen el predicado.
flatMap- Devuelve un stream con el resultado de aplicar una función sobre los elementos del stream. La función produce un stream por cada elemento, que se aplana.
limit- Devuelve un stream de longitud menor o igual que el límite que se le pasa.
map- Devuelve un stream con el resultado de aplicar una función sobre los elementos del stream.
peek- Devuelve este stream, pero aplica una acción al consumir elementos (útil para debugging).
skip- Descarta los n primeros elementos y devuelve el stream con los siguientes.
sorted- Devuelve un stream ordenado de acuerdo al orden natural o a un
Comparator.
Operaciones Terminales
Las operaciones terminales inician el procesamiento del stream y producen un resultado final o un efecto secundario. Después de una operación terminal, el stream no puede ser reutilizado.
allMatch- Devuelve
truesi todos los elementos del stream cumplen el predicado. anyMatch- Devuelve
truesi algún elemento del stream cumple el predicado. findAny- Devuelve un elemento del stream. Se devuelve un
Optionalvacío si el stream está vacío. findFirst- Devuelve el primer elemento del stream (si está desordenado, es uno arbitrario).
noneMatch- Devuelve
truesi ningún elemento del stream cumple el predicado. forEach- Aplica una acción a cada elemento del stream.
reduce- Aplica una operación de reducción que calcula un valor único para el stream.
Ejemplos de Implementación y Utilidades Avanzadas
Ejemplo de Reducción y Observación con peek
Este ejemplo demuestra cómo encadenar operaciones intermedias (peek, filter, map) antes de la operación terminal reduce para calcular la suma de los cuadrados de los números impares.
int sum = Stream.of(1, 2, 3, 4, 5)
.peek(e -> System.out.println("Taking integer: " + e))
.filter(n -> n % 2 == 1)
.peek(e -> System.out.println("Filtered integer: " + e))
.map(n -> n * n)
.peek(e -> System.out.println("Mapped integer: " + e))
.reduce(0, Integer::sum);
Implementación de Predicados Personalizados y Herramientas de Filtrado
Las siguientes clases de utilidad permiten crear y combinar lógicas de filtrado complejas utilizando la interfaz Predicate.
class TestSet<T> implements Predicate<T> {
public Set<T> set;
public TestSet(Collection<T> c) {
this.set = new HashSet<T>(c);
}
@Override
public boolean test(T t) {
return this.set.contains(t);
}
}
class STools {
/**
* Filtra un stream aplicando una combinación OR de múltiples predicados.
*/
public static <T> Stream<T> filterOr(Stream<T> s, Predicate<T>... ps) {
Predicate<T> combinedPred = x -> false;
for (Predicate<T> p : ps) {
combinedPred = combinedPred.or(p);
}
return s.filter(combinedPred);
}
/**
* Filtra un stream si el elemento está contenido en cualquiera de los conjuntos proporcionados.
*/
public static <T> Stream<T> filterSets(Stream<T> s, Set<T>... sets) {
return s.filter(t -> {
for (Set<T> p : sets) {
if (p.contains(t)) return true;
}
return false;
});
}
}