Skip to content

Commit

Permalink
feat(lambda): 🎸 method reference, translated
Browse files Browse the repository at this point in the history
Refers: #6
  • Loading branch information
rcmoutinho committed Sep 12, 2019
1 parent 8064241 commit b46764e
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 116 deletions.
96 changes: 47 additions & 49 deletions book/04-lambda/sections/04-method-reference.asc
Original file line number Diff line number Diff line change
Expand Up @@ -2,172 +2,170 @@
:java-package: src/org/j6toj8/lambda
:section-java-package: ../../../{java-package}

=== Referências a Métodos (Method Reference)
=== Method Reference

.Objetivo
.Objective
--------------------------------------------------
Develop code that uses a method reference, including refactoring a lambda expression to a method reference.
-
Desenvolver código que utiliza uma referência a método, incluindo a refatoração de uma expressão lambda para uma referência a método.
--------------------------------------------------

A sintaxe de referência a um método é uma novidade do Java 8. Com ela é possível fazer referência a métodos específicos, em quatro ocasições diferentes:
The reference syntax for a method is new to Java 8. With it you can reference specific methods on four different occasions:

* Referências a métodos estáticos -> `String::valueOf`
* Referências a métodos de um objeto -> `instanciaDeString::isEmpty`
* Referências a métodos de um tipo de objeto (de uma classe, interface, etc) -> `String::isEmpty`
* Referências a construtores -> `String::new`
* Static Method References -> `String::valueOf`
* Method references of an object -> `instanceString::isEmpty`
* References to methods of an object type (of a class, interface, etc.) -> `String::isEmpty`
* Constructor References -> `String::new`

É 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.
It is essential to remember Functional Interfaces, Lambda Expression syntax variations, and Built-in Interfaces definitions. If necessary, review the sections in this chapter.

É 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.
You can think of method references as another way to write a lambda expression if the only thing your lambda expression does is call another method.

A seguir serão apresentadas as ocasiões em que são utilizadas as referências a métodos.
The following are the occasions when method references are used.

. Chamadas a métodos estáticos em expressões lambda podem virar uma referência ao método.
. Calls to static methods in lambda expressions can become a reference to the method.
+
[source,java,indent=0]
.{java-package}/methodreference/MethodReference_Static.java
----
include::{section-java-package}/methodreference/MethodReference_Static.java[tag=code]
----
+
.Saída no console
.console output
[source,console]
----
5
5
----
+
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`.
In this case the only thing the lambda expression does is take an `x` argument and pass it to the `String` `valueOf` method. To simplify this, Java 8 allows you to write this same lambda function as presented on the following line: `String::valueOf`.
+
Só é possível representar a primeira expressão lambda na forma de um _method reference_ porque:
You can only represent the first lambda expression in the form of a _method reference_ because:
+
* A implementação de `String.valueOf` satisfaz a interface funcional `Function` (recebe um argumento e retorna um valor).
* O argumento de entrada da expressão lambda `x` é exatamente o mesmo passado para o método `String.valueOf(x)`.
* A expressão lambda é simples: somente possui uma chamada a um método.
* The implementation of `String.valueOf` satisfies the `Function` functional interface (takes an argument and returns a value).
* The input argument of the lambda `x` expression is exactly the same as that passed to the `String.valueOf(x)` method.
* The lambda expression is simple: it only has one method call.

. Chamadas a métodos de uma instância específica também podem ser representados como uma referência a um método.
. Method calls from a specific instance can also be represented as a reference to a method.
+
[source,java,indent=0]
.{java-package}/methodreference/MethodReference_Instance.java
----
include::{section-java-package}/methodreference/MethodReference_Instance.java[tag=code]
----
+
.Saída no console
.console output
[source,console]
----
5 - 8
5 - 8
----
+
Só é possível representar a primeira expressão lambda na forma de um _method reference_ porque:
You can only represent the first lambda expression in the form of a _method reference_ because:
+
* A implementação de `Conversor.converte(Integer, Integer)` satisfaz a interface funcional `BiFunction` (recebe dois argumentos e retorna um valor).
* 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)`.
* A expressão lambda é simples: somente possui uma chamada a um método.
* The implementation of `Converter.convert(Integer, Integer)` satisfies the `BiFunction` functional interface (takes two arguments and returns a value).
* The input arguments of the lambda expression `x` and `y` are exactly the same as those passed to the `Converter.convert(Integer, Integer)` method.
* The lambda expression is simple: it only has one method call.

. 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.
. Calls to methods of a class, without specifying the specific instance, can also be represented as a reference to a method.
+
[source,java,indent=0]
.{java-package}/methodreference/MethodReference_Type.java
----
include::{section-java-package}/methodreference/MethodReference_Type.java[tag=code]
----
+
.Saída no console
.console output
[source,console]
----
8.0
8.0
----
+
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:
In this example, reference is being made to the `doubleValue` method of `Integer` *type*. You can only represent the first lambda expression in the form of a _method reference_ because:
+
* Nossa expressão lambda satisfaz a interface funcional `Function` (recebe um argumento `x` e retorna um valor `double`).
* A expressão lambda recebe um argumento `x` do tipo `Integer`, que possui o método `doubleValue` que não recebe parâmetros.
* A expressão lambda é simples: somente possui uma chamada a um método.
* Our lambda expression satisfies the `Function` functional interface (takes an `x` argument and returns a `double` value).
* The lambda expression takes an `x` argument of `Integer` type, which has the `doubleValue` method that takes no parameters.
* The lambda expression is simple: it only has one method call.

. 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.
. You can also use the method reference of a type, as in the previous example, even if the method receives parameters.
+
[source,java,indent=0]
.{java-package}/methodreference/MethodReference_TypeWithParam.java
----
include::{section-java-package}/methodreference/MethodReference_TypeWithParam.java[tag=code]
----
+
.Saída no console
.console output
[source,console]
----
-1
-1
----
+
Nesse exemplo o compilador "descobre" ainda mais coisas que nos exemplos anteriores. Ao escrever apenas a referência ao método, o compilador entende que a variável `x`, que vem primeiro, será a instância de `Integer` onde o método `compareTo` será chamado. E que `y` é a instância de `Integer` que será passada como argumento para o método `compareTo`.
In this example the compiler "discovers" even more things than in the previous examples. By writing only the method reference, the compiler understands that the `x` variable, which comes first, will be the instance of `Integer` where the `compareTo` method will be called. And that `y` is the instance of `Integer` that will be passed as an argument to the `compareTo` method.

. Chamadas a um construtor também podem ser representadas como uma referência a um método.
. Calls to a constructor can also be represented as a reference to a method.
+
[source,java,indent=0]
.{java-package}/methodreference/MethodReference_Constructor.java
----
include::{section-java-package}/methodreference/MethodReference_Constructor.java[tag=code]
----
+
.Saída no console
.console output
[source,console]
----
1
1
----
+
Esse exemplo é muito parecido com o anterior, com a única diferença sendo que o método referenciado é um construtor. Perceba que o construtor também recebe um parâmetro e, assim como no exemplo anterior, o compilador entende que o argumento da função lambda deve ser passado para o construtor que foi chamado.
This example is very similar to the previous one, with the only difference being that the referenced method is a constructor. Note that the constructor also gets a parameter and, as in the previous example, the compiler understands that the lambda function argument must be passed to the called constructor.

. Expressões lambda complexas não podem ser convertidas em referência a método, como a expressão abaixo:
. Complex lambda expressions cannot be converted to method references, like the expression below:
+
[source,java,indent=0]
.{java-package}/methodreference/MethodReference_Complex.java
----
include::{section-java-package}/methodreference/MethodReference_Complex.java[tag=code]
----
+
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.
Since in this case we have another `String` `+ "2"` being added to the constructor, there is no way to represent this with a simple reference to the constructor.

. É 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.
. You can use _method reference_ also with your own classes. See the following example for types created by our code and equivalent lambda expressions with and without reference to methods.
+
[source,java,indent=0]
.{java-package}/methodreference/MethodReference_CustomType.java
----
include::{section-java-package}/methodreference/MethodReference_CustomType.java[tag=code]
----
+
Perceba a diferença entre as expressões lambda:
Note the difference between lambda expressions:
+
* Uma parte implementa a interface functional `Function`, pois recebem um argumento e retornam um valor.
* One part implements the `Function` functional interface, as they take an argument and return a value.
+
* A última implementa a interface functional `Supplier`, pois não recebe argumento, mas retorna um valor.
* The latter implements the `Supplier` functional interface, as it does not take an argument, but returns a value.
+
Em caso de dúvidas, consulte novamente os tipos de interfaces funcionais nas outras seções deste capítulo.
If in doubt, refer back to the types of functional interfaces in the other sections of this chapter.

. A variedade de formas para representar uma mesma expressão lambda pode ser grande, então cuidado para não se confundir.
. The variety of ways to represent the same lambda expression can be large, so be careful not to get confused.
+
[source,java,indent=0]
.{java-package}/methodreference/MethodReference_Variaty.java
----
include::{section-java-package}/methodreference/MethodReference_Variaty.java[tag=code]
----
+
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.
You have seen all the ways to create a lambda expression, from the most complete to the simplest. Make sure you know all these variations for the certification exam.

.Referências
.References
****
* Using Method References
+
Boyarsky, Jeanne; Selikoff, Scott. OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide (p. 152). Wiley. Edição do Kindle.
Boyarsky, Jeanne; Selikoff, Scott. OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide (p. 152). Wiley. Kindle Edition.
* https://www.baeldung.com/java-method-references[Method References in Java.]
* https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html[Method References.] The Java™ Tutorials.
****
****
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ public class MethodReference_Complex {

public static void main(String[] args) {
// tag::code[]
Function<String, Integer> stringParaInteger1 = s -> new Integer(s + "2");
System.out.println(stringParaInteger1.apply("1"));
Function<String, Integer> stringToInteger1 = s -> new Integer(s + "2");
System.out.println(stringToInteger1.apply("1"));
// end::code[]
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ public class MethodReference_Constructor {

public static void main(String[] args) {
// tag::code[]
// representação com expressão lambda
Function<String, Integer> stringParaInteger1 = s -> new Integer(s);
// representação com referência ao construtor
Function<String, Integer> stringParaInteger2 = Integer::new;
// representation with lambda expression
Function<String, Integer> stringToInteger1 = s -> new Integer(s);
// representation with reference to the constructor
Function<String, Integer> stringToInteger2 = Integer::new;

// os resultados serão iguais
System.out.println(stringParaInteger1.apply("1"));
System.out.println(stringParaInteger2.apply("1"));
// the results will be the same
System.out.println(stringToInteger1.apply("1"));
System.out.println(stringToInteger2.apply("1"));
// end::code[]
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,42 @@
public class MethodReference_CustomType {

// tag::code[]
static class SuperHeroi {
private Pessoa pessoa;
static class SuperHero {
private Person person;

public SuperHeroi(Pessoa pessoa) {
this.pessoa = pessoa;
public SuperHero(Person person) {
this.person = person;
}

public static SuperHeroi crieSuperHeroi(Pessoa pessoa) {
return new SuperHeroi(pessoa);
public static SuperHero createSuperHero(Person person) {
return new SuperHero(person);
}

}

static class Pessoa {
static class Person {

public SuperHeroi vireSuperHeroi() {
return new SuperHeroi(this);
public SuperHero becomeSuperHero() {
return new SuperHero(this);
}

}

public static void main(String[] args) {
// expressões lambda equivalentes utilizando chamada a método estático
Function<Pessoa, SuperHeroi> transformaEmHeroiStatic1 = p -> SuperHeroi.crieSuperHeroi(p);
Function<Pessoa, SuperHeroi> transformaEmHeroiStatic2 = SuperHeroi::crieSuperHeroi;
// expressões lambda equivalentes utilizando construtor
Function<Pessoa, SuperHeroi> transformaEmHeroiConstrutor1 = p -> new SuperHeroi(p);
Function<Pessoa, SuperHeroi> transformaEmHeroiConstrutor2 = SuperHeroi::new;
// expressões lambda equivalentes utilizando chamada de método comum, mas referenciando o método da classe
Function<Pessoa, SuperHeroi> transformaEmHeroiClasse1 = p -> p.vireSuperHeroi();
Function<Pessoa, SuperHeroi> transformaEmHeroiClasse2 = Pessoa::vireSuperHeroi;
// expressões lambda equivalentes utilizando chamada de método comum, mas referenciando o método do objeto
Pessoa pessoa = new Pessoa();
Supplier<SuperHeroi> transformaEmHeroiInstancia1 = () -> pessoa.vireSuperHeroi();
Supplier<SuperHeroi> transformaEmHeroiInstancia2 = pessoa::vireSuperHeroi;
// equivalent lambda expressions using static method call
Function<Person, SuperHero> static1 = p -> SuperHero.createSuperHero(p);
Function<Person, SuperHero> static2 = SuperHero::createSuperHero;

// equivalent lambda expressions using constructor
Function<Person, SuperHero> construtor1 = p -> new SuperHero(p);
Function<Person, SuperHero> construtor2 = SuperHero::new;

// equivalent lambda expressions using common method call, but referencing class method
Function<Person, SuperHero> classe1 = p -> p.becomeSuperHero();
Function<Person, SuperHero> classe2 = Person::becomeSuperHero;

// equivalent lambda expressions using common method call, but referencing object method
Person person = new Person();
Supplier<SuperHero> instancia1 = () -> person.becomeSuperHero();
Supplier<SuperHero> instancia2 = person::becomeSuperHero;
}
// end::code[]

Expand Down
20 changes: 10 additions & 10 deletions src/org/j6toj8/lambda/methodreference/MethodReference_Instance.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@
public class MethodReference_Instance {

// tag::code[]
static class Conversor {
public String converte(Integer x, Integer y) {
static class Converter {
public String convert(Integer x, Integer y) {
return String.valueOf(x) + " - " + String.valueOf(y);
}
}

public static void main(String[] args) {
Conversor conversor = new Conversor(); // instância da classe Conversor
Converter converter = new Converter(); // instance of the Converter class

// representação com expressão lambda
BiFunction<Integer, Integer, String> converte1 = (x, y) -> conversor.converte(x, y);
// representação com referência ao método da instância
BiFunction<Integer, Integer, String> converte2 = conversor::converte;
// representation with lambda expression
BiFunction<Integer, Integer, String> convert1 = (x, y) -> converter.convert(x, y);
// representation with reference to instance method
BiFunction<Integer, Integer, String> convert2 = converter::convert;

// os resultados serão iguais
System.out.println(converte1.apply(5, 8));
System.out.println(converte2.apply(5, 8));
// the results will be the same
System.out.println(convert1.apply(5, 8));
System.out.println(convert2.apply(5, 8));
}
// end::code[]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ public class MethodReference_Static {

public static void main(String[] args) {
// tag::code[]
// representação com expressão lambda
Function<Integer, String> converteIntEmStr1 = x -> String.valueOf(x);
// representação com referência ao método
Function<Integer, String> converteIntEmStr2 = String::valueOf;
// representation with lambda expression
Function<Integer, String> convertIntToStr1 = x -> String.valueOf(x);
// representation with reference to the method
Function<Integer, String> convertIntToStr2 = String::valueOf;

System.out.println(converteIntEmStr1.apply(5));
System.out.println(converteIntEmStr2.apply(5));
System.out.println(convertIntToStr1.apply(5));
System.out.println(convertIntToStr2.apply(5));
// end::code[]
}

Expand Down
14 changes: 7 additions & 7 deletions src/org/j6toj8/lambda/methodreference/MethodReference_Type.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ public class MethodReference_Type {

public static void main(String[] args) {
// tag::code[]
// representação com expressão lambda
Function<Integer, Double> intParaDouble1 = x -> x.doubleValue();
// representação com referência ao método doubleValue
Function<Integer, Double> intParaDouble2 = Integer::doubleValue;
// representation with lambda expression
Function<Integer, Double> intToDouble1 = x -> x.doubleValue();
// representation with reference to the doubleValue method
Function<Integer, Double> intToDouble2 = Integer::doubleValue;

// os resultados serão iguais
System.out.println(intParaDouble1.apply(8));
System.out.println(intParaDouble2.apply(8));
// the results will be the same
System.out.println(intToDouble1.apply(8));
System.out.println(intToDouble2.apply(8));
// end::code[]
}

Expand Down
Loading

0 comments on commit b46764e

Please sign in to comment.