Skip to content

Commit 619733a

Browse files
committed
feat(using-streams): exemplos de collectors
Adicionando exemplos da utilização de Collectors. Ref. Issue #23
1 parent c52f8b4 commit 619733a

12 files changed

+402
-12
lines changed

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

Lines changed: 170 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -591,18 +591,176 @@ Nesse caso é passado um argumento adicional. Ele é a função de combinação.
591591

592592
===== Collect
593593

594-
. collect
595-
. joining
596-
. averaging int
597-
. toCollection
598-
. toMap
599-
. toMap (3 param)
600-
. groupingBy
601-
. groupingBy (2 param)
602-
. groupingBy (3 param)
603-
. partitioningBy
604-
. partitioningBy (2 param)
605-
. mapping (2 param)
594+
A operação final `collect` também é um tipo de _Reduce_, porém é utilizada para objetos mutáveis. Ou seja, ao invés de utilizar a operação `reduce` com `String`, provavelmente seria mais eficiente utilizar a operação `collect` com a classe `StringBuilder`, para evitar a criação de vários objetos do tipo `String`. Como Java utiliza muitos objetos mutáveis, incluindo listas e mapas, geralmente a operação `collect` será mais eficiente do que a `reduce`.
595+
596+
Por serem muito comuns, existem vários _Collectors_ já implementados no Java, disponíveis na classe `Collectors`.
597+
598+
. É possível utilizar um `Collector` que junta várias `Strings`.
599+
+
600+
[source,java,indent=0]
601+
.{java-package}/usingstreams/primitives/Streams_CollectorJoining.java
602+
----
603+
include::{section-java-package}/usingstreams/collect/Streams_CollectorJoining.java[tag=code]
604+
----
605+
+
606+
.Saída no console
607+
[source,console]
608+
----
609+
ABC
610+
----
611+
612+
. É possível utilizar um `Collector` para representar cada elemento como um número e calcular a média entre eles.
613+
+
614+
[source,java,indent=0]
615+
.{java-package}/usingstreams/primitives/Streams_CollectorAveragingInt.java
616+
----
617+
include::{section-java-package}/usingstreams/collect/Streams_CollectorAveragingInt.java[tag=code]
618+
----
619+
+
620+
.Saída no console
621+
[source,console]
622+
----
623+
6.2
624+
----
625+
626+
. É possível utilizar um `Collector` para armazenar os elementos de um _Stream_ em uma nova coleção.
627+
+
628+
[source,java,indent=0]
629+
.{java-package}/usingstreams/primitives/Streams_CollectorToCollect.java
630+
----
631+
include::{section-java-package}/usingstreams/collect/Streams_CollectorToCollect.java[tag=code]
632+
----
633+
+
634+
.Saída no console
635+
[source,console]
636+
----
637+
ArrayList: [1, 2, 3, 4]
638+
HashSet: [1, 2, 3, 4]
639+
LinkedList: [1, 2, 3, 4]
640+
TreeSet: [1, 2, 3, 4]
641+
----
642+
643+
. É possível utilizar um `Collector` para armazenar os elementos de um _Stream_ em um mapa.
644+
+
645+
[source,java,indent=0]
646+
.{java-package}/usingstreams/primitives/Streams_CollectorToMap.java
647+
----
648+
include::{section-java-package}/usingstreams/collect/Streams_CollectorToMap.java[tag=code]
649+
----
650+
+
651+
.Saída no console
652+
[source,console]
653+
----
654+
{Roseany=7, Amélia=6, Rodrigo=7, Rinaldo=7, Luiz=4}
655+
----
656+
657+
. Também é possível armazenar em um mapa para casos em que a chave for se repetir.
658+
+
659+
[source,java,indent=0]
660+
.{java-package}/usingstreams/primitives/Streams_CollectorToMapDuplicateKey.java
661+
----
662+
include::{section-java-package}/usingstreams/collect/Streams_CollectorToMapDuplicateKey.java[tag=code]
663+
----
664+
+
665+
.Saída no console
666+
[source,console]
667+
----
668+
{4=Luiz, 6=Amélia, 7=Rinaldo,Rodrigo,Roseany}
669+
----
670+
671+
. É possível utilizar um `Collector` que cria um mapa agrupando valores que tem a mesma chave em uma lista.
672+
+
673+
[source,java,indent=0]
674+
.{java-package}/usingstreams/primitives/Streams_CollectorGroupingBy.java
675+
----
676+
include::{section-java-package}/usingstreams/collect/Streams_CollectorGroupingBy.java[tag=code]
677+
----
678+
+
679+
.Saída no console
680+
[source,console]
681+
----
682+
{4=[Luiz], 6=[Amélia], 7=[Rinaldo, Rodrigo, Roseany]}
683+
----
684+
685+
. Também é possível agrupar personalizando como valores que tem a mesma chave serão combinados.
686+
+
687+
[source,java,indent=0]
688+
.{java-package}/usingstreams/primitives/Streams_CollectorGroupingByDownstream.java
689+
----
690+
include::{section-java-package}/usingstreams/collect/Streams_CollectorGroupingByDownstream.java[tag=code]
691+
----
692+
+
693+
.Saída no console
694+
[source,console]
695+
----
696+
{4=Luiz, 6=Amélia, 7=Rinaldo,Rodrigo,Roseany}
697+
----
698+
+
699+
Perceba que nesse caso os valores foram combinados utilizando outro _Collector_, que agrupou os nomes separando com vírgula.
700+
701+
. Também é possível definir qual tipo de mapa será utilizado para agrupar.
702+
+
703+
[source,java,indent=0]
704+
.{java-package}/usingstreams/primitives/Streams_CollectorGroupingByMapFactory.java
705+
----
706+
include::{section-java-package}/usingstreams/collect/Streams_CollectorGroupingByMapFactory.java[tag=code]
707+
----
708+
+
709+
.Saída no console
710+
[source,console]
711+
----
712+
{4=Luiz, 6=Amélia, 7=Rinaldo,Rodrigo,Roseany}
713+
----
714+
+
715+
Perceba que o resultado desse exemplo é idêntico ao anterior, porém foi passado um argumento a mais, que é o construtor do mapa que deveria ser utilizado.
716+
717+
. É possível utilizar um `Collector` que particiona valores em `True` ou `False` a partir de um função do tipo `Predicate`.
718+
+
719+
[source,java,indent=0]
720+
.{java-package}/usingstreams/primitives/Streams_CollectorPartitioningBy.java
721+
----
722+
include::{section-java-package}/usingstreams/collect/Streams_CollectorPartitioningBy.java[tag=code]
723+
----
724+
+
725+
.Saída no console
726+
[source,console]
727+
----
728+
{false=[Luiz, Amélia], true=[Rinaldo, Rodrigo, Roseany]}
729+
----
730+
+
731+
Perceba que nesse caso a regra de particionamento são os nomes que iniciam-se por `R`.
732+
733+
. Também é possível personalizar como a combinação dos valores particionados será feita.
734+
+
735+
[source,java,indent=0]
736+
.{java-package}/usingstreams/primitives/Streams_CollectorPartitioningByDownstream.java
737+
----
738+
include::{section-java-package}/usingstreams/collect/Streams_CollectorPartitioningByDownstream.java[tag=code]
739+
----
740+
+
741+
.Saída no console
742+
[source,console]
743+
----
744+
{false=Luiz,Amélia, true=Rinaldo,Rodrigo,Roseany}
745+
----
746+
+
747+
Perceba que nesse caso os valores foram combinados utilizando um outro `Collector`, que juntou os valores daquela mesma chave em uma única `String` separados por vírgula.
748+
749+
. É possível ainda adicionar uma camada a mais de transformação ao utilizar um `Collector`, utilizando o método `mapping`.
750+
+
751+
[source,java,indent=0]
752+
.{java-package}/usingstreams/primitives/Streams_CollectorMapping.java
753+
----
754+
include::{section-java-package}/usingstreams/collect/Streams_CollectorMapping.java[tag=code]
755+
----
756+
+
757+
.Saída no console
758+
[source,console]
759+
----
760+
{4=LUIZ, 6=AMÉLIA, 7=RINALDO,RODRIGO,ROSEANY}
761+
----
762+
+
763+
Esse tipo de código, apesar de complexo, pode aparecer no exame de certificação. É recomendado praticar esses exemplos com uma IDE para entender de fato seus comportamentos.
606764

607765
.Referências
608766
****
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.j6toj8.streams.usingstreams.collect;
2+
3+
import java.util.stream.Collectors;
4+
import java.util.stream.Stream;
5+
6+
public class Streams_CollectorAveragingInt {
7+
8+
public static void main(String[] args) {
9+
// tag::code[]
10+
// Calcula a média do tamanho de cada nome
11+
Double collect = Stream.of("Rinaldo", "Rodrigo", "Luiz", "Amélia", "Roseany")
12+
.collect(Collectors.averagingInt(s -> s.length()));
13+
14+
System.out.println(collect);
15+
// end::code[]
16+
}
17+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.j6toj8.streams.usingstreams.collect;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
import java.util.stream.Collectors;
6+
import java.util.stream.Stream;
7+
8+
public class Streams_CollectorGroupingBy {
9+
10+
public static void main(String[] args) {
11+
// tag::code[]
12+
// Armazena o resultado do Stream em um Mapa
13+
// A Chave é o tamanho do nome
14+
// O Valor é uma lista com os nomes que tem aquele tamanho
15+
Map<Object, List<String>> collect = Stream.of("Rinaldo", "Rodrigo", "Luiz", "Amélia", "Roseany")
16+
.collect(Collectors.groupingBy(s -> s.length()));
17+
18+
System.out.println(collect);
19+
// end::code[]
20+
}
21+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.j6toj8.streams.usingstreams.collect;
2+
3+
import java.util.Map;
4+
import java.util.stream.Collectors;
5+
import java.util.stream.Stream;
6+
7+
public class Streams_CollectorGroupingByDownstream {
8+
9+
public static void main(String[] args) {
10+
// tag::code[]
11+
// Armazena o resultado do Stream em um Mapa
12+
// A Chave é o tamanho do nome
13+
// O Valor são os nomes que tem aquele tamanho
14+
Map<Object, String> collect = Stream.of("Rinaldo", "Rodrigo", "Luiz", "Amélia", "Roseany")
15+
.collect(Collectors.groupingBy(s -> s.length(), Collectors.joining(",")));
16+
17+
System.out.println(collect);
18+
// end::code[]
19+
}
20+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.j6toj8.streams.usingstreams.collect;
2+
3+
import java.util.Map;
4+
import java.util.TreeMap;
5+
import java.util.stream.Collectors;
6+
import java.util.stream.Stream;
7+
8+
public class Streams_CollectorGroupingByMapFactory {
9+
10+
public static void main(String[] args) {
11+
// tag::code[]
12+
// Armazena o resultado do Stream em um Mapa
13+
// A Chave é o tamanho do nome
14+
// O Valor são os nomes que tem aquele tamanho
15+
Map<Object, String> collect = Stream.of("Rinaldo", "Rodrigo", "Luiz", "Amélia", "Roseany")
16+
.collect(Collectors.groupingBy(s -> s.length(), TreeMap::new, Collectors.joining(",")));
17+
18+
System.out.println(collect);
19+
// end::code[]
20+
}
21+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.j6toj8.streams.usingstreams.collect;
2+
3+
import java.util.stream.Collectors;
4+
import java.util.stream.Stream;
5+
6+
public class Streams_CollectorJoining {
7+
8+
public static void main(String[] args) {
9+
// tag::code[]
10+
String collect = Stream.of("A", "B", "C")
11+
.collect(Collectors.joining());
12+
13+
System.out.println(collect);
14+
// end::code[]
15+
}
16+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.j6toj8.streams.usingstreams.collect;
2+
3+
import java.util.Map;
4+
import java.util.stream.Collectors;
5+
import java.util.stream.Stream;
6+
7+
public class Streams_CollectorMapping {
8+
9+
public static void main(String[] args) {
10+
// tag::code[]
11+
// Armazena o resultado do Stream em um Mapa
12+
// A Chave é o tamanho do nome
13+
// O Valor são os nomes que tem aquele tamanho, convertidos para maiúscula, separados por vírgula
14+
Map<Integer, String> collect = Stream.of("Rinaldo", "Rodrigo", "Luiz", "Amélia", "Roseany")
15+
.collect(Collectors.groupingBy(s -> s.length(), Collectors.mapping(s -> s.toUpperCase(), Collectors.joining(","))));
16+
17+
System.out.println(collect);
18+
// end::code[]
19+
}
20+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.j6toj8.streams.usingstreams.collect;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
import java.util.stream.Collectors;
6+
import java.util.stream.Stream;
7+
8+
public class Streams_CollectorPartitioningBy {
9+
10+
public static void main(String[] args) {
11+
// tag::code[]
12+
// Armazena o resultado do Stream em um Mapa
13+
// As Chaves são true ou false
14+
// O Valor é uma lista dos valores que atendem ou não a regra de particionamento
15+
Map<Boolean, List<String>> collect = Stream.of("Rinaldo", "Rodrigo", "Luiz", "Amélia", "Roseany")
16+
.collect(Collectors.partitioningBy(s -> s.startsWith("R")));
17+
18+
System.out.println(collect);
19+
// end::code[]
20+
}
21+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.j6toj8.streams.usingstreams.collect;
2+
3+
import java.util.Map;
4+
import java.util.stream.Collectors;
5+
import java.util.stream.Stream;
6+
7+
public class Streams_CollectorPartitioningByDownstream {
8+
9+
public static void main(String[] args) {
10+
// tag::code[]
11+
// Armazena o resultado do Stream em um Mapa
12+
// As Chaves são true ou false
13+
// O Valor é uma String que são os nomes que atendem ou não a regra de particionamento
14+
Map<Boolean, String> collect = Stream.of("Rinaldo", "Rodrigo", "Luiz", "Amélia", "Roseany")
15+
.collect(Collectors.partitioningBy(s -> s.startsWith("R"), Collectors.joining(",")));
16+
17+
System.out.println(collect);
18+
// end::code[]
19+
}
20+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.j6toj8.streams.usingstreams.collect;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.HashSet;
6+
import java.util.LinkedList;
7+
import java.util.TreeSet;
8+
import java.util.stream.Collectors;
9+
import java.util.stream.Stream;
10+
11+
public class Streams_CollectorToCollect {
12+
13+
public static void main(String[] args) {
14+
// tag::code[]
15+
// Armazena o resultado do Stream em um ArrayList
16+
Collection<Integer> collect = Stream.of(1, 2, 3, 4)
17+
.collect(Collectors.toCollection(ArrayList::new));
18+
System.out.println("ArrayList: " + collect);
19+
20+
// Armazena o resultado do Stream em um HashSet
21+
Collection<Integer> collect2 = Stream.of(1, 2, 3, 4)
22+
.collect(Collectors.toCollection(HashSet::new));
23+
System.out.println("HashSet: " + collect2);
24+
25+
// Armazena o resultado do Stream em uma LinkedList
26+
Collection<Integer> collect3 = Stream.of(1, 2, 3, 4)
27+
.collect(Collectors.toCollection(LinkedList::new));
28+
System.out.println("LinkedList: " + collect3);
29+
30+
// Armazena o resultado do Stream em um TreeSet
31+
Collection<Integer> collect4 = Stream.of(1, 2, 3, 4)
32+
.collect(Collectors.toCollection(TreeSet::new));
33+
System.out.println("TreeSet: " + collect4);
34+
// end::code[]
35+
}
36+
}

0 commit comments

Comments
 (0)