Skip to content

Commit 7685536

Browse files
committed
feat(method-reference): melhorias e exemplos
Acrescentado 2 novos exemplos para elucidar melhor a questão, e alterado algumas descrições para ficar mais claro. Issue #22
1 parent 72c83fe commit 7685536

File tree

4 files changed

+110
-13
lines changed

4 files changed

+110
-13
lines changed

book/04-lambda/sections/04-method-reference.asc

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@ A sintaxe de referência a um método é uma novidade do Java 8. Com ela é poss
1414

1515
* Referências a métodos estáticos -> `String::valueOf`
1616
* Referências a métodos de um objeto -> `instanciaDeString::isEmpty`
17-
* Referências a métodos de um tipo de objeto -> `String::isEmpty`
17+
* Referências a métodos de um tipo de objeto (de uma classe, interface, etc) -> `String::isEmpty`
1818
* Referências a construtores -> `String::new`
1919

20-
A seguir serão apresentadas as ocasiões em que cada uma dessas referências é útil.
20+
É essencial lembrar das Interfaces Funcionais, das variações de sintaxe de Expressões Lambda e das definições de Interfaces Funcionais Pré-Construídas. Caso julgue necessário, reveja as seções deste capítulo.
21+
22+
É possível pensar nas referências a métodos como uma outra forma de escrever uma expressão lambda, caso a única coisa que sua expressão lambda faça seja chamar um outro método.
23+
24+
A seguir serão apresentadas as ocasiões em que são utilizadas as referências a métodos.
2125

2226
. Chamadas a métodos estáticos em expressões lambda podem virar uma referência ao método.
2327
+
@@ -34,13 +38,15 @@ include::{section-java-package}/methodreference/MethodReference_Static.java[tag=
3438
5
3539
----
3640
+
37-
Essa utilização de _method reference_ só é possível porque:
41+
Nesse caso a única coisa que a expressão lambda faz é receber um argumento `x` e repassar para o método `valueOf` de `String`. Para simplificar isso, o Java 8 permite que você escreva essa mesma função lambda como foi apresentado na linha seguinte: `String::valueOf`.
3842
+
39-
* A implementação de `String.valueOf(int)` satisfaz a interface funcional `Function` (recebe um argumento e retorna um valor).
43+
Só é possível representar a primeira expressão lambda na forma de um _method reference_ porque:
44+
+
45+
* A implementação de `String.valueOf` satisfaz a interface funcional `Function` (recebe um argumento e retorna um valor).
4046
* O argumento de entrada da expressão lambda `x` é exatamente o mesmo passado para o método `String.valueOf(x)`.
41-
* Essa é a única chamada que essa expressão lambda faz.
47+
* A expressão lambda é simples: somente possui uma chamada a um método.
4248

43-
. Chamadas a métodos de uma instância também podem ser representados como uma referência a um método.
49+
. Chamadas a métodos de uma instância específica também podem ser representados como uma referência a um método.
4450
+
4551
[source,java,indent=0]
4652
.{java-package}/methodreference/MethodReference_Instance.java
@@ -55,13 +61,13 @@ include::{section-java-package}/methodreference/MethodReference_Instance.java[ta
5561
5 - 8
5662
----
5763
+
58-
Essa utilização de _method reference_ só é possível porque:
64+
Só é possível representar a primeira expressão lambda na forma de um _method reference_ porque:
5965
+
6066
* A implementação de `Conversor.converte(Integer, Integer)` satisfaz a interface funcional `BiFunction` (recebe dois argumentos e retorna um valor).
6167
* Os argumentos de entrada da expressão lambda `x` e `y` são exatamente os mesmos passados para o método `Conversor.converte(Integer, Integer)`.
62-
* Essa é a única chamada que essa expressão lambda faz.
68+
* A expressão lambda é simples: somente possui uma chamada a um método.
6369

64-
. Chamadas a métodos de um tipo específico, sem especificar a instância, também podem ser representados como uma referência a um método.
70+
. Chamadas a métodos de uma classe, sem especificar a instância específica, também podem ser representados como uma referência a um método.
6571
+
6672
[source,java,indent=0]
6773
.{java-package}/methodreference/MethodReference_Type.java
@@ -76,11 +82,11 @@ include::{section-java-package}/methodreference/MethodReference_Type.java[tag=co
7682
8.0
7783
----
7884
+
79-
Nesse exemplo, a referência está sendo feita ao método `doubleValue` do *tipo* `Integer`. Essa utilização de _method reference_ só é possível porque:
85+
Nesse exemplo, a referência está sendo feita ao método `doubleValue` do *tipo* `Integer`. Só é possível representar a primeira expressão lambda na forma de um _method reference_ porque:
8086
+
81-
* Nossa expressão lambda satisfaz a interface funcional `Function` (recebe um argumento e retorna um valor).
87+
* Nossa expressão lambda satisfaz a interface funcional `Function` (recebe um argumento `x` e retorna um valor `double`).
8288
* A expressão lambda recebe um argumento `x` do tipo `Integer`, que possui o método `doubleValue` que não recebe parâmetros.
83-
* Essa é a única chamada que essa expressão lambda faz.
89+
* A expressão lambda é simples: somente possui uma chamada a um método.
8490

8591
. Também é possível utilizar a referência ao método de um tipo, como no exemplo anterior, mesmo que o método receba parâmetros.
8692
+
@@ -126,6 +132,24 @@ include::{section-java-package}/methodreference/MethodReference_Complex.java[tag
126132
+
127133
Como nesse caso temos uma outra `String` `+ "2"` sendo acrescentada no construtor, não há como representar isso com uma simples referência ao construtor.
128134

135+
. É possível utilizar _method reference_ também com suas própria classes. Veja no exemplo a seguir os tipos criados pelo nosso código e as expressões lambda equivalentes com e sem referência a métodos.
136+
+
137+
[source,java,indent=0]
138+
.{java-package}/methodreference/MethodReference_CustomType.java
139+
----
140+
include::{section-java-package}/methodreference/MethodReference_CustomType.java[tag=code]
141+
----
142+
143+
. A variedade de formas para representar uma mesma expressão lambda pode ser grande, então cuidado para não se confundir.
144+
+
145+
[source,java,indent=0]
146+
.{java-package}/methodreference/MethodReference_Variaty.java
147+
----
148+
include::{section-java-package}/methodreference/MethodReference_Variaty.java[tag=code]
149+
----
150+
+
151+
Você já viu todas as formas de criar uma expressão lambda, desde a mais completa até a mais simples. Tenha certeza que conhece todas essas variações para o exame de certificação.
152+
129153
.Referências
130154
****
131155
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package org.j6toj8.lambda.methodreference;
2+
3+
import java.util.function.Function;
4+
import java.util.function.Supplier;
5+
6+
public class MethodReference_CustomType {
7+
8+
// tag::code[]
9+
static class SuperHeroi {
10+
private Pessoa pessoa;
11+
12+
public SuperHeroi(Pessoa pessoa) {
13+
this.pessoa = pessoa;
14+
}
15+
16+
public static SuperHeroi crieSuperHeroi(Pessoa pessoa) {
17+
return new SuperHeroi(pessoa);
18+
}
19+
20+
}
21+
22+
static class Pessoa {
23+
24+
public SuperHeroi vireSuperHeroi() {
25+
return new SuperHeroi(this);
26+
}
27+
28+
}
29+
30+
public static void main(String[] args) {
31+
// expressões lambda equivalentes utilizando chamada a método estático
32+
Function<Pessoa, SuperHeroi> transformaEmHeroiStatic1 = p -> SuperHeroi.crieSuperHeroi(p);
33+
Function<Pessoa, SuperHeroi> transformaEmHeroiStatic2 = SuperHeroi::crieSuperHeroi;
34+
35+
// expressões lambda equivalentes utilizando construtor
36+
Function<Pessoa, SuperHeroi> transformaEmHeroiConstrutor1 = p -> new SuperHeroi(p);
37+
Function<Pessoa, SuperHeroi> transformaEmHeroiConstrutor2 = SuperHeroi::new;
38+
39+
// expressões lambda equivalentes utilizando chamada de método comum, mas referenciando o método da classe
40+
Function<Pessoa, SuperHeroi> transformaEmHeroiClasse1 = p -> p.vireSuperHeroi();
41+
Function<Pessoa, SuperHeroi> transformaEmHeroiClasse2 = Pessoa::vireSuperHeroi;
42+
43+
// expressões lambda equivalentes utilizando chamada de método comum, mas referenciando o método do objeto
44+
Pessoa pessoa = new Pessoa();
45+
Supplier<SuperHeroi> transformaEmHeroiInstancia1 = () -> pessoa.vireSuperHeroi();
46+
Supplier<SuperHeroi> transformaEmHeroiInstancia2 = pessoa::vireSuperHeroi;
47+
}
48+
// end::code[]
49+
50+
}

src/org/j6toj8/lambda/methodreference/MethodReference_Type.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public static void main(String[] args) {
88
// tag::code[]
99
// representação com expressão lambda
1010
Function<Integer, Double> intParaDouble1 = x -> x.doubleValue();
11-
// representação com referência ao método d
11+
// representação com referência ao método doubleValue
1212
Function<Integer, Double> intParaDouble2 = Integer::doubleValue;
1313

1414
// os resultados serão iguais
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.j6toj8.lambda.methodreference;
2+
3+
import java.util.function.Function;
4+
5+
public class MethodReference_Variaty {
6+
7+
public static void main(String[] args) {
8+
// tag::code[]
9+
// ATENÇÃO! Todas essas expressões lambda são equivalentes!
10+
11+
Function<Integer, String> lambda1 = (Integer x) -> { return String.valueOf(x); };
12+
Function<Integer, String> lambda2 = (x) -> { return String.valueOf(x); };
13+
Function<Integer, String> lambda3 = x -> { return String.valueOf(x); };
14+
15+
Function<Integer, String> lambda4 = (Integer x) -> String.valueOf(x);
16+
Function<Integer, String> lambda5 = (x) -> String.valueOf(x);
17+
Function<Integer, String> lambda6 = x -> String.valueOf(x);
18+
19+
Function<Integer, String> lambda7 = String::valueOf;
20+
// end::code[]
21+
}
22+
23+
}

0 commit comments

Comments
 (0)