Spliterator: divisão para paralelismo
Implemente um Spliterator personalizado para disponibilizar dados do domínio como uma fonte de stream divisível.
Spliterator: divisão para paralelismo é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.
O que é um Spliterator?
Um Spliterator (iterador divisível) é o mecanismo central por trás dos fluxos. Ele percorre os elementos e pode dividir a si próprio em duas partes para processamento paralelo.
Principais métodos de Spliterator
Quatro métodos principais: tryAdvance (processa um elemento), forEachRemaining (processa todos os elementos restantes), trySplit (divide em dois) e estimateSize (estima a quantidade 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
Os Spliterators declaram suas características com sinalizadores 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, SUBSIZEDComo trySplit funciona
trySplit() retorna um novo Spliterator que abrange aproximadamente metade dos elementos restantes. O original abrange a outra metade. Retorne null se não for possível dividir.
// ArrayList Spliterator splits efficiently at midpoint:
// [0,1,2,3,4,5] -> [0,1,2] (new) + [3,4,5] (original)Criando um Spliterator personalizado
Implemente Spliterator<T> para expor uma estrutura de dados personalizada como fonte de um fluxo. Defina trySplit para habilitar o 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; }
}Criando um fluxo a partir de um Spliterator
Use StreamSupport.stream(spliterator, parallel) para criar um fluxo a partir de qualquer Spliterator — a ponte entre fontes de dados personalizadas e a API Stream.
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 uma árvore binária
Spliterators personalizados habilitam o paralelismo em estruturas que não são listas, como árvores. trySplit retorna o Spliterator da subárvore esquerda e mantém a direita.
Eficiência do paralelismo e qualidade da divisão
Os fluxos paralelos dividem os dados recursivamente até que os blocos sejam pequenos o suficiente para uma única linha de execução. Uma boa divisão exige que estimateSize seja preciso e que as partes tenham tamanhos aproximadamente iguais.
forEachRemaining para processamento em lote
Se não for necessário dividir, substitua forEachRemaining para realizar o processamento em lote e evitar o custo por elemento de chamar tryAdvance em um laço.
@Override
public void forEachRemaining(Consumer<? super Integer> action) {
for (int i = start; i < end; i++) action.accept(i);
start = end; // mark as exhausted
}Spliterator versus Iterator
Iterator: somente sequencial, sem indicação de tamanho e sem divisão. Spliterator: capaz de operar em paralelo, fornece características e uma estimativa de tamanho e foi projetado para a API Stream.
Verificação rápida
O que trySplit() retorna quando não é possível dividir?
Recapitulação
Spliterator é o mecanismo dos fluxos paralelos. Implemente tryAdvance, trySplit, estimateSize e characteristics para expor estruturas de dados personalizadas como fluxos. Use StreamSupport.stream(sp, true) para operar em paralelo.
Perguntas Frequentes
A aula “Spliterator: divisão para paralelismo” é grátis?
Sim — o texto completo de “Spliterator: divisão para paralelismo” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.
O que vou aprender em “Spliterator: divisão para paralelismo”?
Implemente um Spliterator personalizado para disponibilizar dados do domínio como uma fonte de stream divisível. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Java Academy?
Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Spliterator: divisão para paralelismo”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Java Academy?
Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- flatMap para coleções aninhadas
- Streams paralelos: desempenho e armadilhas
- Spliterator: divisão para paralelismo
- Streams infinitos com iterate e generate