Skip to content

Commit a952f4d

Browse files
committed
feat(built-in-interfaces): exemplos de interfaces
Exemplos para todas as interfaces funcionais do pacote java.util.function, inclusive falando sobre tipos primitivos. Ainda falta a parte de Optional e mais exemplos de cenários reais onde utilizar as interfaces funcionais. Issue #21
1 parent 1a18568 commit a952f4d

12 files changed

+457
-0
lines changed

book/04-lambda/sections/03-built-in-interfaces.asc

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,261 @@ Develop code that uses the built-in interfaces included in the java.util.functio
1010
Desenvolver código que usa as interfaces embutidas no pacote java.util.function, como Function, Consumer, Supplier, UnaryOperator, Predicate e a API de Optional, incluindo as variações de tipos primitivos e binários das interfaces
1111
--------------------------------------------------
1212

13+
==== `Supplier`
14+
15+
. `Supplier` é uma interface funcional que não recebe nenhum parâmetro de entrada, mas retorna um valor. Sua definição na JDK é a seguinte:
16+
+
17+
[source,java,indent=0]
18+
.java.util.function.Supplier<T>
19+
----
20+
@FunctionalInterface
21+
public interface Supplier<T> {
22+
T get();
23+
}
24+
----
25+
26+
. Uma implementação possível para um `Supplier` é um gerador da data atual:
27+
+
28+
[source,java,indent=0]
29+
.{java-package}/builtininterfaces/BuiltInInterfaces_SupplierExample.java
30+
----
31+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_SupplierExample.java[tag=code]
32+
----
33+
+
34+
.Saída no console
35+
[source,console]
36+
----
37+
2019-07-08
38+
----
39+
+
40+
A saída no console irá imprimir a data atual. Está sendo apresentada a data em que este código foi escrito.
41+
+
42+
Perceba que a expressão lambda está simplificada, sem chaves `{}` ou `return`. Caso tenha dúvidas com relação a isso, consulte novamente a seção sobre expressões lambda.
43+
44+
. Um `Supplier` pode ser utilizado para fornecer uma função custosa, para que seja chamada apenas se for necessário:
45+
+
46+
[source,java,indent=0]
47+
.{java-package}/builtininterfaces/BuiltInInterfaces_SupplierUseCase.java
48+
----
49+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_SupplierUseCase.java[tag=code]
50+
----
51+
+
52+
.Saída no console
53+
[source,console]
54+
----
55+
Menor de idade!
56+
Maior de idade! Validação realizada às 2019-07-09T00:21:35.488
57+
----
58+
+
59+
Perceba que neste caso o supplier só precisou ser chamado na segunda vez, evitando uma execução desnecessária da expressão lambda.
60+
61+
. Existem interfaces `Supplier` para lidar tipos primitivos: `BooleanSupplier`, `IntSupplier`, `LongSupplier` e `DoubleSupplier`.
62+
+
63+
[source,java,indent=0]
64+
.{java-package}/builtininterfaces/BuiltInInterfaces_SupplierPrimitive.java
65+
----
66+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_SupplierPrimitive.java[tag=code]
67+
----
68+
+
69+
O resultado na console será imprimir o `int` primitivo gerado aleatoriamente.
70+
71+
==== `Consumer` e `BiConsumer`
72+
73+
. `Consumer` é uma interface funcional que recebe um parâmetro de entrada, e não retorna nenhum valor. Sua definição na JDK é a seguinte:
74+
+
75+
[source,java,indent=0]
76+
.java.util.function.Supplier<T>
77+
----
78+
@FunctionalInterface
79+
public interface Consumer<T> {
80+
void accept(T t);
81+
}
82+
----
83+
84+
. `BiConsumer` é uma interface funcional que recebe dois parâmetros de entrada, e não retorna nenhum valor. Sua definição na JDK é a seguinte:
85+
+
86+
[source,java,indent=0]
87+
.java.util.function.Consumer<T>
88+
----
89+
@FunctionalInterface
90+
public interface BiConsumer<T, U> {
91+
void accept(T t, U u);
92+
}
93+
----
94+
95+
. Implementações possíveis para `Consumer` ou `BiConsumer` são funções que imprimem informações no console:
96+
+
97+
[source,java,indent=0]
98+
.{java-package}/builtininterfaces/BuiltInInterfaces_ConsumerExample.java
99+
----
100+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_ConsumerExample.java[tag=code]
101+
----
102+
+
103+
.Saída no console
104+
[source,console]
105+
----
106+
2019-07-08
107+
----
108+
109+
. Existem interfaces `Consumer` para lidar tipos primitivos: `DoubleConsumer`, `IntConsumer`, `LongConsumer`, `ObjDoubleConsumer`, `ObjIntConsumer` e `ObjLongConsumer`.
110+
+
111+
[source,java,indent=0]
112+
.{java-package}/builtininterfaces/BuiltInInterfaces_ConsumerPrimitive.java
113+
----
114+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_ConsumerPrimitive.java[tag=code]
115+
----
116+
117+
==== `Predicate` e `BiPredicate`
118+
119+
. `Predicate` é uma interface funcional que recebe um parâmetro de entrada e retorna um valor booleano. Sua definição na JDK é a seguinte:
120+
+
121+
[source,java,indent=0]
122+
.java.util.function.Predicate<T>
123+
----
124+
@FunctionalInterface
125+
public interface Predicate<T> {
126+
boolean test(T t);
127+
}
128+
----
129+
130+
. `BiPredicate` é uma interface funcional que recebe dois parâmetros de entrada e retorna um valor booleano. Sua definição na JDK é a seguinte:
131+
+
132+
[source,java,indent=0]
133+
.java.util.function.BiPredicate<T>
134+
----
135+
@FunctionalInterface
136+
public interface BiPredicate<T, U> {
137+
boolean test(T t, U u);
138+
}
139+
----
140+
141+
. Implementações possíveis para `Predicate` ou `BiPredicate` são funções que verificam se o valor de entrada é igual ao valor sorteado:
142+
+
143+
[source,java,indent=0]
144+
.{java-package}/builtininterfaces/BuiltInInterfaces_PredicateExample.java
145+
----
146+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_PredicateExample.java[tag=code]
147+
----
148+
+
149+
A saída no console é aleatória, pois depende do valor sorteado. Um valor possível seria `false` e `true`.
150+
151+
. Existem interfaces `Predicate` para lidar tipos primitivos: `DoublePredicate`, `IntPredicate` e `LongPredicate`.
152+
+
153+
[source,java,indent=0]
154+
.{java-package}/builtininterfaces/BuiltInInterfaces_PredicatePrimitive.java
155+
----
156+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_PredicatePrimitive.java[tag=code]
157+
----
158+
159+
==== `Function` e `BiFunction`
160+
161+
. `Function` é uma interface funcional que recebe um parâmetro de entrada e retorna um valor. Sua definição na JDK é a seguinte:
162+
+
163+
[source,java,indent=0]
164+
.java.util.function.Function<T, R>
165+
----
166+
@FunctionalInterface
167+
public interface Function<T, R> {
168+
R apply(T t);
169+
}
170+
----
171+
172+
. `BiFunction` é uma interface funcional que recebe dois parâmetros de entrada e retorna um valor. Sua definição na JDK é a seguinte:
173+
+
174+
[source,java,indent=0]
175+
.java.util.function.BiFunction<T>
176+
----
177+
@FunctionalInterface
178+
public interface BiFunction<T, U, R> {
179+
R apply(T t, U u);
180+
}
181+
----
182+
183+
. Implementações possíveis para `Function` ou `BiFunction` são funções que multiplicam os valores fornecidos:
184+
+
185+
[source,java,indent=0]
186+
.{java-package}/builtininterfaces/BuiltInInterfaces_FunctionExample.java
187+
----
188+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_FunctionExample.java[tag=code]
189+
----
190+
+
191+
.Saída no console
192+
[source,console]
193+
----
194+
7.5
195+
30.0
196+
----
197+
198+
. Existem várias interfaces `Function` para lidar tipos primitivos: `DoubleFunction`, `DoubleToIntFunction`, `DoubleToLongFunction`, `IntFunction`, `IntToDoubleFunction`, `IntToLongFunction`, `LongFunction`, `LongToDoubleFunction`, `LongToIntFunction`, `ToDoubleBiFunction`, `ToDoubleFunction`, `ToIntBiFunction`, `ToIntFunction`, `ToLongBiFunction`, `ToLongFunction`.
199+
+
200+
[source,java,indent=0]
201+
.{java-package}/builtininterfaces/BuiltInInterfaces_FunctionPrimitive.java
202+
----
203+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_FunctionPrimitive.java[tag=code]
204+
----
205+
+
206+
.Saída no console
207+
[source,console]
208+
----
209+
7.5
210+
30.0
211+
----
212+
213+
==== `UnaryOperator` e `BinaryOperator`
214+
215+
. `UnaryOperator` é uma interface funcional que recebe um parâmetro de entrada e retorna um valor do mesmo tipo da entrada. Sua definição na JDK é a seguinte:
216+
+
217+
[source,java,indent=0]
218+
.java.util.function.Function<T, R>
219+
----
220+
@FunctionalInterface
221+
public interface UnaryOperator<T> extends Function<T, T> {
222+
223+
}
224+
----
225+
+ Perceba que não existe método abstrato declarado, pois ela apenas estende a interface `Function` já existente.
226+
227+
. `BinaryOperator` é uma interface funcional que recebe dois parâmetros de entrada do mesmo tipo, e retorna um valor do mesmo tipo das entradas. Sua definição na JDK é a seguinte:
228+
+
229+
[source,java,indent=0]
230+
.java.util.function.BiFunction<T>
231+
----
232+
@FunctionalInterface
233+
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
234+
235+
}
236+
----
237+
+ Perceba que não existe método abstrato declarado, pois ela apenas estende a interface `BiFunction` já existente.
238+
239+
. Implementações possíveis para `UnaryOperator` ou `BinaryOperator` são funções que soma um número fixo ou soma um número ao outro:
240+
+
241+
[source,java,indent=0]
242+
.{java-package}/builtininterfaces/BuiltInInterfaces_OperatorExample.java
243+
----
244+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_OperatorExample.java[tag=code]
245+
----
246+
+
247+
.Saída no console
248+
[source,console]
249+
----
250+
9
251+
6
252+
----
253+
254+
. Existem interfaces `Operator` para lidar tipos primitivos: `DoubleBinaryOperator`, `DoubleUnaryOperator`, `IntBinaryOperator`, `IntUnaryOperator`, `LongBinaryOperator`, `LongUnaryOperator`.
255+
+
256+
[source,java,indent=0]
257+
.{java-package}/builtininterfaces/BuiltInInterfaces_OperatorPrimitive.java
258+
----
259+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_OperatorPrimitive.java[tag=code]
260+
----
261+
+
262+
.Saída no console
263+
[source,console]
264+
----
265+
9
266+
6
267+
----
13268

14269
.Referências
15270
****
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.j6toj8.lambda.builtininterfaces;
2+
3+
import java.time.LocalDate;
4+
import java.time.LocalTime;
5+
import java.util.function.BiConsumer;
6+
import java.util.function.Consumer;
7+
8+
public class BuiltInInterfaces_ConsumerExample {
9+
10+
// tag::code[]
11+
public static void main(String[] args) {
12+
Consumer<Object> impressor = x -> System.out.println(x);
13+
impressor.accept(LocalDate.now()); // imprimirá a data atual
14+
15+
BiConsumer<Object, Object> impressor2 = (x, y) -> { System.out.println(x); System.out.println(y); };
16+
impressor2.accept(LocalDate.now(), LocalTime.now()); // imprimirá a data atual e depois a hora atual
17+
}
18+
// end::code[]
19+
20+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.j6toj8.lambda.builtininterfaces;
2+
3+
import java.time.LocalDate;
4+
import java.util.function.IntConsumer;
5+
import java.util.function.ObjIntConsumer;
6+
7+
public class BuiltInInterfaces_ConsumerPrimitive {
8+
9+
// tag::code[]
10+
public static void main(String[] args) {
11+
IntConsumer impressor = x -> System.out.println(x);
12+
impressor.accept(5); // imprimirá '5'
13+
14+
ObjIntConsumer<Object> impressor2 = (x, y) -> { System.out.println(x); System.out.println(y); };
15+
impressor2.accept(LocalDate.now(), 5); // imprimirá a data atual e depois '5'
16+
}
17+
// end::code[]
18+
19+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.j6toj8.lambda.builtininterfaces;
2+
3+
import java.util.function.BiFunction;
4+
import java.util.function.Function;
5+
6+
public class BuiltInInterfaces_FunctionExample {
7+
8+
// tag::code[]
9+
public static void main(String[] args) {
10+
Function<Integer, Double> duplica = x -> x * 2.5;
11+
System.out.println(duplica.apply(3)); // multiplica 3 * 2.5
12+
13+
BiFunction<Integer, Integer, Double> multiplicaEDuplica = (x, y) -> x * y * 2.5;
14+
System.out.println(multiplicaEDuplica.apply(3, 4)); // multiplica 3 * 4 * 2.5
15+
}
16+
// end::code[]
17+
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.j6toj8.lambda.builtininterfaces;
2+
3+
import java.util.function.IntToDoubleFunction;
4+
import java.util.function.ToDoubleBiFunction;
5+
6+
public class BuiltInInterfaces_FunctionPrimitive {
7+
8+
// tag::code[]
9+
public static void main(String[] args) {
10+
IntToDoubleFunction duplica = x -> x * 2.5;
11+
System.out.println(duplica.applyAsDouble(3)); // multiplica 3 * 2.5
12+
13+
ToDoubleBiFunction<Integer, Integer> multiplicaEDuplica = (x, y) -> x * y * 2.5;
14+
System.out.println(multiplicaEDuplica.applyAsDouble(3, 4)); // multiplica 3 * 4 * 2.5
15+
}
16+
// end::code[]
17+
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.j6toj8.lambda.builtininterfaces;
2+
3+
import java.util.function.BinaryOperator;
4+
import java.util.function.UnaryOperator;
5+
6+
public class BuiltInInterfaces_OperatorExample {
7+
8+
// tag::code[]
9+
public static void main(String[] args) {
10+
UnaryOperator<Integer> somaDois = x -> x + 2;
11+
System.out.println(somaDois.apply(7)); // soma 7 + 2
12+
13+
BinaryOperator<Integer> somaNumeros = (x, y) -> x + y;
14+
System.out.println(somaNumeros.apply(1, 5)); // soma 1 + 5
15+
}
16+
// end::code[]
17+
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.j6toj8.lambda.builtininterfaces;
2+
3+
import java.util.function.IntBinaryOperator;
4+
import java.util.function.IntUnaryOperator;
5+
6+
public class BuiltInInterfaces_OperatorPrimitive {
7+
8+
// tag::code[]
9+
public static void main(String[] args) {
10+
IntUnaryOperator somaDois = x -> x + 2;
11+
System.out.println(somaDois.applyAsInt(7)); // soma 7 + 2
12+
13+
IntBinaryOperator somaNumeros = (x, y) -> x + y;
14+
System.out.println(somaNumeros.applyAsInt(1, 5)); // soma 1 + 5
15+
}
16+
// end::code[]
17+
18+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.j6toj8.lambda.builtininterfaces;
2+
3+
import java.util.Random;
4+
import java.util.function.BiPredicate;
5+
import java.util.function.Predicate;
6+
7+
public class BuiltInInterfaces_PredicateExample {
8+
9+
// tag::code[]
10+
public static void main(String[] args) {
11+
Predicate<Integer> dado = x -> x.equals(new Random().nextInt(7));
12+
System.out.println(dado.test(1)); // testa se o número gerado é igual a 1
13+
14+
BiPredicate<Integer, Integer> dadoDuplo = (x, y) -> x.equals(new Random().nextInt(7)) || y.equals(new Random().nextInt(7));
15+
System.out.println(dadoDuplo.test(1, 2)); // testa se o primeiro número gerado é igual a 1
16+
// ou se o segundo número gerado é igual a 2
17+
}
18+
// end::code[]
19+
20+
}

0 commit comments

Comments
 (0)