You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: book/05-java-streams/sections/01-using-streams.asc
+33-36Lines changed: 33 additions & 36 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,16 +10,16 @@ Describe the Stream interface and pipelines; create a stream by using the Arrays
10
10
Descrever a interface e pipelines de Stream; criar um stream utilizando os métodos Arrays.stream() e IntStream.range(); identificar quais operações lambda executam sob demanda (_lazy_).
Uma das maiores novidades do Java 8 são os __Streams__. Um _Stream_ é basicamente um fluxo de dados.
14
-
Os dados podem ser __Strings__, números, ou qualquer outro objeto. Esses dados passam por uma série de operações, e o conjunto dessas operações é chamado de __pipeline__. Essas operações são quase sempre representadas por expressões lambda, então é muito importante ter dominado todo o capítulo sobre **lambda**, pois todos aqueles conceitos serão utilizados agora para formar um __Stream__.
13
+
Uma das maiores novidades do Java 8 são os _Streams_. Um _Stream_ é basicamente um fluxo de dados.
14
+
Os dados podem ser _Strings_, números, ou qualquer outro objeto. Esses dados passam por uma série de operações, e o conjunto dessas operações é chamado de _pipeline_. Essas operações são quase sempre representadas por expressões lambda, então é muito importante ter dominado todo o capítulo sobre *lambda*, pois todos aqueles conceitos serão utilizados agora para formar um _Stream_.
15
15
16
16
A partir dos exemplos a seguir, essa explicação ficará mais clara.
17
17
18
18
==== Criando um _Stream_
19
19
20
-
Geralmente, um _Stream_ é criado a partir de um conjunto de dados, como uma lista ou outro tipo de coleção. O objeteivo da certificação deixa explícito que é necessário conhecer os métodos `Arrays.stream()` e ``IntStream.range()``. Mas, além dessas, serão apresentadas também algumas outras formas comuns de criar um __Stream__.
20
+
Geralmente, um _Stream_ é criado a partir de um conjunto de dados, como uma lista ou outro tipo de coleção. O objeteivo da certificação deixa explícito que é necessário conhecer os métodos `Arrays.stream()` e `IntStream.range()`. Mas, além dessas, serão apresentadas também algumas outras formas comuns de criar um _Stream_.
21
21
22
-
. É possível criar um Stream a partir de um `Array` utilizando o método ``Arrays.stream()``.
22
+
. É possível criar um Stream a partir de um `Array` utilizando o método `Arrays.stream()`.
. É possível criar um Stream a partir de uma faixa de números utilizando o método `IntStream.range()`.
41
39
+
@@ -91,15 +89,15 @@ B
91
89
4.0
92
90
----
93
91
+
94
-
Nesse caso foi criado um _Stream_ que contém: ``String``, ``Character``, ``Integer``, ``Long``, `Float` e ``Double``.
92
+
Nesse caso foi criado um _Stream_ que contém: `String`, `Character`, `Integer`, `Long`, `Float` e `Double`.
95
93
96
94
==== Operações em _Streams_
97
95
98
-
As operações feitas em um _Stream_ irão formar seu __pipeline__. As operações que podem ser realizadas em um Stream são divididas em *operações intermediárias* e **operações finais**. O _Stream_ pode conter inúmeras operações intermediárias, porém somente uma final. Nos exemplos anteriores a única operação utilizada foi o ``forEach``, que é uma operação final. A seguir serão apresentadas outras operações.
96
+
As operações feitas em um _Stream_ irão formar seu _pipeline_. As operações que podem ser realizadas em um Stream são divididas em *operações intermediárias* e **operações finais**. O _Stream_ pode conter inúmeras operações intermediárias, porém somente uma final. Nos exemplos anteriores a única operação utilizada foi o `forEach`, que é uma operação final. A seguir serão apresentadas outras operações.
99
97
100
98
===== Operações intermediárias
101
99
102
-
. É possível ignorar elementos de um stream com a operaçao ``skip``.
100
+
. É possível ignorar elementos de um stream com a operaçao `skip`.
Perceba que nesse caso os elementos 0 e 1 foram ignorados, pois são os dois primeiros elementos do __Stream__. Isso ocorreu pela existência da operação ``skip``.
115
+
Perceba que nesse caso os elementos 0 e 1 foram ignorados, pois são os dois primeiros elementos do _Stream_. Isso ocorreu pela existência da operação `skip`.
118
116
119
-
. É possível limitar a quantidade de elementos que serão processados utilizando a operação ``limit``.
117
+
. É possível limitar a quantidade de elementos que serão processados utilizando a operação `limit`.
Perceba que nesse caso os elementos repetidos do stream (``"A"`` e ``"B"``) foram ignorados, sendo apresentados apenas uma vez.
168
+
Perceba que nesse caso os elementos repetidos do stream (`"A"` e `"B"`) foram ignorados, sendo apresentados apenas uma vez.
171
169
+
172
-
A operação `distinct` utiliza os método `equals` e ``hashCode``, então tenha certeza de que eles estão implementados corretamente caso esteja utilizando um tipo de objeto criado por você. No exemplo foram utilizados objetos do tipo `String`, que já possuem essa implementação por padrão.
170
+
A operação `distinct` utiliza os método `equals` e `hashCode`, então tenha certeza de que eles estão implementados corretamente caso esteja utilizando um tipo de objeto criado por você. No exemplo foram utilizados objetos do tipo `String`, que já possuem essa implementação por padrão.
173
171
174
-
. É possível aplicar uma transformação nos elementos do Stream utilizando a operação ``map``.
172
+
. É possível aplicar uma transformação nos elementos do Stream utilizando a operação `map`.
Perceba que nesse caso os elementos sofreram uma transformação, que foi a multiplicação por 2, antes de serem impressos no console.
192
190
193
-
. É possível ordenar os elementos de um Stream utilizando a operação ``sorted``.
191
+
. É possível ordenar os elementos de um Stream utilizando a operação `sorted`.
194
192
+
195
193
[source,java,indent=0]
196
194
.{java-package}/usingstreams/Streams_Sorted.java
@@ -212,9 +210,9 @@ T
212
210
Y
213
211
----
214
212
+
215
-
Nesse caso todos os elementos são ordenados utilizando a ordem natural dos objetos ``String``, pois eles já implementam a interface ``Comparable``, sendo apresentados em ordem alfabética. Também existe uma versão do método `sort` que recebe como argumento uma implementação de ``Comparator``, caso deseje ordenar de outra forma.
213
+
Nesse caso todos os elementos são ordenados utilizando a ordem natural dos objetos `String`, pois eles já implementam a interface `Comparable`, sendo apresentados em ordem alfabética. Também existe uma versão do método `sort` que recebe como argumento uma implementação de `Comparator`, caso deseje ordenar de outra forma.
216
214
217
-
. É possível observar os elementos que passam por um _Stream_ utilizando a operação ``peek``.
215
+
. É possível observar os elementos que passam por um _Stream_ utilizando a operação `peek`.
218
216
+
219
217
[source,java,indent=0]
220
218
.{java-package}/usingstreams/Streams_Peek.java
@@ -235,9 +233,9 @@ Peek: A
235
233
ForEach: A
236
234
----
237
235
+
238
-
A operação `peek` funciona apenas para observar o que está passando pelo __Stream__. Pode ser muito útil para realizar _debug_ ou _log_. Nesse caso os elementos estão sendo impressos duas vezes no console, pois o método `peek` e o `forEach` estão ambos realizando essa mesma ação. Porém, em aplicações reais, geralmente a operação final *não* será um ``forEach``, de tal forma que fará sentido utilizar o ``peek``.
236
+
A operação `peek` funciona apenas para observar o que está passando pelo _Stream_. Pode ser muito útil para realizar _debug_ ou _log_. Nesse caso os elementos estão sendo impressos duas vezes no console, pois o método `peek` e o `forEach` estão ambos realizando essa mesma ação. Porém, em aplicações reais, geralmente a operação final *não* será um `forEach`, de tal forma que fará sentido utilizar o `peek`.
239
237
240
-
. É possível transformar um _Stream_ de vários `Arrays` em um único _Stream_ *contínuo* utilizando o método ``flatMap``.
238
+
. É possível transformar um _Stream_ de vários `Arrays` em um único _Stream_ *contínuo* utilizando o método `flatMap`.
241
239
+
242
240
[source,java,indent=0]
243
241
.{java-package}/usingstreams/Streams_FlatMap.java
@@ -259,14 +257,13 @@ H
259
257
I
260
258
----
261
259
+
262
-
Perceba que nesse caso existem 3 `Arrays` distintos. Então cria-se um _Stream_ contendo 3 ``Arrays``. O cenário comum seria um que cada elemento do _Stream_ fosse um objeto do tipo ``Array``. Porém, ao utilizar a operação `flatMap`, é criado um _Stream_ para cada um desses ``Arrays``, que são unidos e formam um único _Stream_ contínuo.
260
+
Perceba que nesse caso existem 3 `Arrays` distintos. Então cria-se um _Stream_ contendo 3 `Arrays`. O cenário comum seria um que cada elemento do _Stream_ fosse um objeto do tipo `Array`. Porém, ao utilizar a operação `flatMap`, é criado um _Stream_ para cada um desses `Arrays`, que são unidos e formam um único _Stream_ contínuo.
263
261
264
262
===== Operações finais
265
263
266
-
. É possível executar uma ação final para cada elemento do _Stream_ utilizando a operação ``forEach``, conforme demonstrado nos exemplos anteriores.
264
+
. É possível executar uma ação final para cada elemento do _Stream_ utilizando a operação `forEach`, conforme demonstrado nos exemplos anteriores.
267
265
268
-
. É possível recuperar o maior e o menor valor de um _Stream_ utilizando as operações finais `max` e ``min``.
269
-
. É possível recuperar a quantidade de elementos de um _Stream_ utilizando a operação final ``count``.
266
+
. É possível recuperar o maior e o menor valor de um _Stream_ utilizando as operações finais `max` e `min`. E também é possível recuperar a quantidade de elementos de um _Stream_ utilizando a operação final `count`.
No caso das operações `max` e `min`, é necessário passar como argumento qual comparador será utilizado. Como os números possuem uma ordem natural, isto é, implementam a interface ``Comparable``, é possível utilizar um comparador que usa essa ordem natural, que é o ``Comparator.naturalOrder()``. Caso seja um tipo de objeto que não possui uma ordem natural, é necessário passar como argumento uma outra implementação de ``Comparator``.
282
+
No caso das operações `max` e `min`, é necessário passar como argumento qual comparador será utilizado. Como os números possuem uma ordem natural, isto é, implementam a interface `Comparable`, é possível utilizar um comparador que usa essa ordem natural, que é o `Comparator.naturalOrder()`. Caso seja um tipo de objeto que não possui uma ordem natural, é necessário passar como argumento uma outra implementação de `Comparator`.
286
283
287
-
. É possível pegar o primeiro elemento do Stream utilizando a operação final ``findFirst``, ou um elemento qualquer com ``findAny``.
284
+
. É possível pegar o primeiro elemento do Stream utilizando a operação final `findFirst`, ou um elemento qualquer com `findAny`.
Nesse caso, como o _Stream_ é sequencial e não paralelo, os dois resultados são iguais. Em _Streams_ paralelos, que serão apresentados em uma próxima seção, a operação `findAny` pode trazer resultados diferentes.
303
300
304
-
. É possível verificar se os elementos do _Stream_ atendem a alguma validação utilizando as operações finais ``allMatch``, ``anyMatch`` e `noneMatch`.
301
+
. É possível verificar se os elementos do _Stream_ atendem a alguma validação utilizando as operações finais `allMatch`, `anyMatch` e `noneMatch`.
305
302
+
306
303
[source,java,indent=0]
307
304
.{java-package}/usingstreams/Streams_Match.java
@@ -319,7 +316,7 @@ noneMatch: false
319
316
+
320
317
Perceba que na primeira operação é verificado se *qualquer* elemento é maior do que 5. Na segunda, se *todos* os elementos são maiores do que 5. E na terceira, se *nenhum* elemento é maior do que 5.
321
318
322
-
. Não é possível chamar mais de uma operação final no mesmo __Stream__.
319
+
. Não é possível chamar mais de uma operação final no mesmo _Stream_.
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
383
387
-
. É possível encadear a operação final do _Stream_ utilizando expressões lambda na classe ``Optional``.
384
+
. É possível encadear a operação final do _Stream_ utilizando expressões lambda na classe `Optional`.
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__.
392
+
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_.
396
393
397
-
===== Execução sob-demanda (__lazy__)
394
+
===== Execução sob-demanda (_lazy_)
398
395
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.
396
+
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
397
401
398
. Nada será feito se o _Stream_ não contiver uma operação final.
402
399
+
@@ -406,7 +403,7 @@ As operações intermediárias de um _Stream_ só são executadas quando necess
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.
406
+
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.
410
407
411
408
. Outras operações intermediárias também não costumam ser executadas se não for necessário.
412
409
+
@@ -427,7 +424,7 @@ Peek: 2
427
424
ForEach: 2
428
425
----
429
426
+
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.
427
+
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.
0 commit comments