Spliterator: división para el paralelismo
Implemente un Spliterator personalizado para exponer datos de dominio como una fuente de stream divisible.
Spliterator: división para el paralelismo es una lección gratuita de Java Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Java Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Java Academy incluye 4 lecciones en total.
¿Qué es un Spliterator?
Un Spliterator (iterador divisible) es el mecanismo central en el que se basan los streams. Recorre los elementos y puede dividirse en dos partes para procesarlos en paralelo.
Métodos principales de Spliterator
Hay cuatro métodos principales: tryAdvance (procesa un elemento), forEachRemaining (procesa todos los elementos restantes), trySplit (divide en dos) y estimateSize (estima el número de elementos).
Spliterator<Integer> sp = List.of(1,2,3,4,5,6).spliterator();
Spliterator<Integer> half = sp.trySplit(); // splits off first ~half
half.forEachRemaining(System.out::println); // 1 2 3
sp.forEachRemaining(System.out::println); // 4 5 6Características de Spliterator
Los Spliterators declaran sus características mediante indicadores de bits: SIZED, ORDERED, DISTINCT, SORTED, NONNULL, IMMUTABLE, CONCURRENT, SUBSIZED.
Spliterator<String> sp = List.of("a","b","c").spliterator();
System.out.println(Integer.toBinaryString(sp.characteristics()));
// Characteristics include ORDERED, SIZED, SUBSIZEDCómo funciona trySplit
trySplit() devuelve un Spliterator nuevo que abarca aproximadamente la mitad de los elementos restantes. El original abarca la otra mitad. Devuelve null si no es posible dividir.
// ArrayList Spliterator splits efficiently at midpoint:
// [0,1,2,3,4,5] -> [0,1,2] (new) + [3,4,5] (original)Crear un Spliterator personalizado
Implemente Spliterator<T> para exponer una estructura de datos personalizada como fuente de un stream. Defina trySplit para habilitar el paralelismo.
public class RangeSpliterator implements Spliterator<Integer> {
private int start, end;
public RangeSpliterator(int start, int end) { this.start=start; this.end=end; }
public boolean tryAdvance(Consumer<? super Integer> action) {
if (start >= end) return false;
action.accept(start++); return true;
}
public Spliterator<Integer> trySplit() {
int mid = (start + end) / 2;
if (mid <= start) return null;
RangeSpliterator prefix = new RangeSpliterator(start, mid);
this.start = mid; return prefix;
}
public long estimateSize() { return end - start; }
public int characteristics() { return ORDERED | SIZED | SUBSIZED | IMMUTABLE; }
}Crear un stream a partir de un Spliterator
Use StreamSupport.stream(spliterator, parallel) para crear un stream a partir de cualquier spliterator: es el puente entre las fuentes de datos personalizadas y la Stream API.
Spliterator<Integer> sp = new RangeSpliterator(0, 1_000_000);
Stream<Integer> stream = StreamSupport.stream(sp, true); // true = parallel
long count = stream.filter(n -> n % 2 == 0).count();
System.out.println(count); // 500000Spliterator para un árbol binario
Los Spliterators personalizados permiten aplicar el paralelismo a estructuras que no son listas, como los árboles. trySplit devuelve el Spliterator del subárbol izquierdo y conserva el derecho.
Eficiencia del paralelismo y calidad de la división
Los streams paralelos dividen los datos de forma recursiva hasta que los bloques son lo bastante pequeños para un solo hilo. Una buena división requiere que estimateSize sea preciso y que las divisiones tengan tamaños aproximadamente iguales.
forEachRemaining para el procesamiento masivo
Si no es necesario dividir, sobrescriba forEachRemaining para procesar elementos en bloque y evitar la sobrecarga por elemento de llamar a tryAdvance dentro de un bucle.
@Override
public void forEachRemaining(Consumer<? super Integer> action) {
for (int i = start; i < end; i++) action.accept(i);
start = end; // mark as exhausted
}Spliterator frente a Iterator
Iterator: solo secuencial, sin indicación del tamaño y sin división. Spliterator: admite paralelismo, proporciona características y una estimación del tamaño, y está diseñado para la Stream API.
Comprobación rápida
¿Qué devuelve trySplit() cuando no es posible dividir?
Repaso
Spliterator es el motor de los streams paralelos. Implemente tryAdvance, trySplit, estimateSize y characteristics para exponer estructuras de datos personalizadas como streams. Use StreamSupport.stream(sp, true) para ejecutarlos en paralelo.
Preguntas frecuentes
¿La lección «Spliterator: división para el paralelismo» es gratis?
Sí — el texto completo de «Spliterator: división para el paralelismo» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Java Academy, actualiza a CoddyKit PRO. El curso de Java Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Spliterator: división para el paralelismo»?
Implemente un Spliterator personalizado para exponer datos de dominio como una fuente de stream divisible. Practicas Java Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Java Academy?
No se requiere experiencia previa. Java Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «Spliterator: división para el paralelismo»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Java Academy?
Sí. Cada lección de Java Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- flatMap para colecciones anidadas
- Streams paralelos: rendimiento y dificultades
- Spliterator: división para el paralelismo
- Streams infinitos con iterate y generate