Skip to content

Commit e6ef9f1

Browse files
committed
feat(using-streams): pipeline e lazy
Adicionando explicação e exemplos de Pipeline de Stream, e as explicações sobre a execução sob-demanda de operações (lazy). Ref. Issue #23
1 parent c638d08 commit e6ef9f1

File tree

6 files changed

+176
-5
lines changed

6 files changed

+176
-5
lines changed

book/05-java-streams/sections/01-using-streams.asc

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -341,15 +341,93 @@ Exception in thread "main" java.lang.IllegalStateException: stream has already b
341341

342342
===== Pipeline
343343

344-
. Exemplos com várias operações
345-
. Mudar a lista depois de criar o Stream
346-
. Encadeamento de chamada com Optional
344+
. É possível criar um _pipeline_ com várias operações em um único __Stream__.
345+
+
346+
[source,java,indent=0]
347+
.{java-package}/usingstreams/Streams_Pipeline.java
348+
----
349+
include::{section-java-package}/usingstreams/Streams_Pipeline.java[tag=code]
350+
----
351+
+
352+
.Saída no console
353+
[source,console]
354+
----
355+
8
356+
12
357+
----
358+
+
359+
Para entender todas as operações realizadas nesse pipeline, é necessário entender passo a passo:
360+
+
361+
.. Foi criado um _Stream_ contendo todos os números de 0 a 9
362+
.. Foi aplicado um filtro mantendo apenas os números pares: 0, 2, 4, 6 e 8
363+
.. Foram ignorados os dois primeiros números, mantendo apenas: 4, 6 e 8
364+
.. Foi limitado o processamento aos dois primeiros números: 4 e 6
365+
.. Foi aplicada uma multiplicação por 2 em cada elemento, resultando em: 8 e 12
366+
.. Os dois elementos foram impressos no console.
367+
368+
. O Stream só será criado de fato depois que alguma operação for executada nele.
369+
+
370+
[source,java,indent=0]
371+
.{java-package}/usingstreams/Streams_ChangeBackingList.java
372+
----
373+
include::{section-java-package}/usingstreams/Streams_ChangeBackingList.java[tag=code]
374+
----
375+
+
376+
.Saída no console
377+
[source,console]
378+
----
379+
1
380+
2
381+
3
382+
4
383+
----
384+
+
385+
Perceba que, mesmo que o _Stream_ aparentemente tenha sido criado antes de adicionar o número 4 na lista, ele imprime esse número no console. Isso acontece porque o _Stream_ só foi criado de fato quando alguma operação foi feita nele, ou seja, quando o `forEach` foi invocado.
386+
387+
. É possível encadear a operação final do _Stream_ utilizando expressões lambda na classe ``Optional``.
388+
+
389+
[source,java,indent=0]
390+
.{java-package}/usingstreams/Streams_Optional.java
391+
----
392+
include::{section-java-package}/usingstreams/Streams_Optional.java[tag=code]
393+
----
394+
+
395+
Perceba que o método `ifPresent` é da classe `Optional`, mesmo que no segundo exemplo possa parecer que ele faz parte do __Stream__. Em outras palavras, a operação final é `max`, e `ifPresent` é uma chamada em `Optional` e não mais no __Stream__.
347396

348397
===== Execução sob-demanda (__lazy__)
349398

350-
<Explicação>
399+
As operações intermediárias de um _Stream_ só são executadas quando necessário. Ou seja, mesmo que a operação esteja presente no __pipeline__, não é certeza de que ela será executada.
400+
401+
. Nada será feito se o _Stream_ não contiver uma operação final.
402+
+
403+
[source,java,indent=0]
404+
.{java-package}/usingstreams/Streams_LazyNoFinal.java
405+
----
406+
include::{section-java-package}/usingstreams/Streams_LazyNoFinal.java[tag=code]
407+
----
408+
+
409+
Nesse caso nada é impresso no console, pois *nenhuma* operação *final* foi aplicada no __Stream__. Ou seja, se não há nada consumindo o resultado desse __Stream__, o Java nem precisa executar o _pipeline_ criado.
351410

352-
. Exemplos de lazy
411+
. Outras operações intermediárias também não costumam ser executadas se não for necessário.
412+
+
413+
[source,java,indent=0]
414+
.{java-package}/usingstreams/Streams_LazyMap.java
415+
----
416+
include::{section-java-package}/usingstreams/Streams_LazyMap.java[tag=code]
417+
----
418+
+
419+
.Saída no console
420+
[source,console]
421+
----
422+
Peek: 0
423+
ForEach: 0
424+
Peek: 1
425+
ForEach: 1
426+
Peek: 2
427+
ForEach: 2
428+
----
429+
+
430+
Perceba que, mesmo que a operação `peek` esteja antes da operação `limit`, ela não é executada para todos os elementos do ``Stream``, apenas para aqueles que serão realmente utilizados.
353431

354432
.Referências
355433
****
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.j6toj8.streams.usingstreams;
2+
3+
import java.util.ArrayList;
4+
import java.util.stream.Stream;
5+
6+
public class Streams_ChangeBackingList {
7+
8+
public static void main(String[] args) {
9+
// tag::code[]
10+
ArrayList<Integer> list = new ArrayList<Integer>();
11+
list.add(1);
12+
list.add(2);
13+
list.add(3);
14+
15+
Stream<Integer> stream = list.stream();
16+
17+
list.add(4);
18+
19+
stream.forEach(System.out::println);
20+
// end::code[]
21+
}
22+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.j6toj8.streams.usingstreams;
2+
3+
import java.util.stream.IntStream;
4+
5+
public class Streams_LazyMap {
6+
7+
public static void main(String[] args) {
8+
// tag::code[]
9+
IntStream.range(0, 10)
10+
.peek(e -> System.out.println("Peek: " + e))
11+
.limit(3)
12+
.forEach(e -> System.out.println("ForEach: " + e));
13+
// end::code[]
14+
}
15+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.j6toj8.streams.usingstreams;
2+
3+
import java.util.stream.IntStream;
4+
5+
public class Streams_LazyNoFinal {
6+
7+
public static void main(String[] args) {
8+
// tag::code[]
9+
IntStream.range(0, 4)
10+
.filter(e -> e % 2 == 0)
11+
.limit(3)
12+
.map(e -> e * 2)
13+
.peek(System.out::println);
14+
// end::code[]
15+
}
16+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.j6toj8.streams.usingstreams;
2+
3+
import java.util.Comparator;
4+
import java.util.Optional;
5+
import java.util.stream.Stream;
6+
7+
public class Streams_Optional {
8+
9+
public static void main(String[] args) {
10+
// tag::code[]
11+
// Exemplo sem encadear a chamada de Optional
12+
Optional<Integer> max = Stream.of(7, 2, 1)
13+
.max(Comparator.naturalOrder());
14+
15+
max.ifPresent(System.out::println);
16+
17+
// Exemplo encadeando a chamada de Optional
18+
Stream.of(7, 2, 1)
19+
.max(Comparator.naturalOrder())
20+
.ifPresent(System.out::println);
21+
// end::code[]
22+
}
23+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.j6toj8.streams.usingstreams;
2+
3+
import java.util.stream.IntStream;
4+
5+
public class Streams_Pipeline {
6+
7+
public static void main(String[] args) {
8+
// tag::code[]
9+
IntStream.range(0, 10) // Stream de 0 a 9
10+
.filter(e -> e % 2 == 0) // mantém apenas números pares
11+
.skip(2) // ignora os dois primeiros
12+
.limit(2) // limita a 3 elementos
13+
.map(e -> e * 2) // multipla cada elemento por 2
14+
.forEach(System.out::println); // imprime cada elemento
15+
// end::code[]
16+
}
17+
}

0 commit comments

Comments
 (0)