Skip to content

Commit 75183f0

Browse files
committed
Revert "quitando ejemplos no vistos en clase"
This reverts commit c4749a5.
1 parent 6b85fca commit 75183f0

2 files changed

Lines changed: 349 additions & 0 deletions

File tree

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package com.platzi.functional._05_sam;
2+
3+
import java.util.List;
4+
import java.util.Scanner;
5+
6+
public class SingleAbstractMethod {
7+
/**
8+
* Se le considera SAM a una interface cuando tiene un unico metodo, sin valor definido.
9+
* Por ejemplo:
10+
*/
11+
interface SAMInterface {
12+
int doSomething();
13+
}
14+
15+
/**
16+
* Si la interface tiene mas de un metodo sin implementacion, no es considerada una SAM
17+
*/
18+
interface NotASAMInterface {
19+
int doFoo();
20+
21+
void doBar();
22+
}
23+
24+
//
25+
//
26+
//
27+
//
28+
//
29+
//
30+
//
31+
//
32+
//
33+
//
34+
//
35+
//
36+
//
37+
//
38+
//
39+
//
40+
//
41+
//
42+
//
43+
44+
/**
45+
* Este concepto es importante empezando en Java 8 por varias razones, la principal
46+
* es que el compilador nos permitira usar una anotacion disponible UNICAMENTE para
47+
* SAMs: @FunctionalInterface
48+
*/
49+
@FunctionalInterface
50+
interface AnotherSAM {
51+
String getText();
52+
}
53+
54+
/**
55+
* De nuevo, esto solo funciona en interfaces de tipo SAM
56+
*/
57+
// @FunctionalInterface
58+
interface NotAValidSAM {
59+
String getText();
60+
61+
String getSubText();
62+
}
63+
64+
//
65+
//
66+
//
67+
//
68+
//
69+
//
70+
//
71+
//
72+
//
73+
//
74+
//
75+
//
76+
//
77+
@FunctionalInterface
78+
interface MySAMInterfaceIsAlsoAFunction {
79+
String someMethod(int x);
80+
}
81+
82+
83+
/**
84+
* Con las interfaces anotadas, podemos usar la forma de lambdas/funciones para definir
85+
* el comportamiento
86+
*/
87+
private static void fooSAM() {
88+
MySAMInterfaceIsAlsoAFunction myFunction = x -> "Result: " + x;
89+
}
90+
91+
//
92+
//
93+
//
94+
//
95+
//
96+
//
97+
//
98+
//
99+
//
100+
//
101+
//
102+
//
103+
//
104+
105+
/**
106+
* Incluso en interfaces con muchos parametros
107+
*/
108+
@FunctionalInterface
109+
interface OverComplicatedSAM {
110+
int someWeirdNameForAMethod(String s, int x, Scanner sc, List<Double> values);
111+
}
112+
113+
public static void somethingCalling() {
114+
OverComplicatedSAM stillAFunction = (s, x, sc, list) -> 0;
115+
}
116+
}
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
package com.platzi.functional._06_reference_operator;
2+
3+
import com.platzi.functional.util.Utils;
4+
5+
import java.util.LinkedList;
6+
import java.util.List;
7+
import java.util.function.Consumer;
8+
import java.util.function.Function;
9+
10+
public class _01_Operator {
11+
/**
12+
* Un pequeño ejemplo de como el operador :: funciona
13+
*/
14+
public static void main(String[] args) {
15+
List<String> names = new LinkedList<>();
16+
names.add("Fer");
17+
names.add("Orly");
18+
names.add("Sier");
19+
names.add("Chris");
20+
names.add("Eryx");
21+
22+
//Procesamos en una lambda
23+
names.forEach(s -> System.out.println(s));
24+
25+
//
26+
//
27+
//
28+
//
29+
//
30+
31+
//Pero sabemos algunas cosas de este punto:
32+
/*
33+
1. forEach toma un Consumer<T>
34+
2. System.out.println(Object obj) es un metodo que toma un elemento y no tiene retorno
35+
3. Los Consumer son funciones que toman un elemento y no retornan un resultado…
36+
37+
… Entonces …
38+
39+
System.out.println puede funcionar como un Consumer!
40+
*/
41+
42+
//
43+
//
44+
//
45+
//
46+
//
47+
//
48+
49+
//En efecto…
50+
names.forEach(System.out::println);
51+
52+
//
53+
//
54+
//
55+
//
56+
//
57+
//
58+
///
59+
//
60+
61+
//Pero no solo eso, la cuestion esta en que toda funcion cuya definicon sea:
62+
//
63+
// void nombre(Type type)
64+
//
65+
// puede ser usada siempre que el tipo de parametro sea el mismo.
66+
names.forEach(_01_Operator::coolStuffWithAString);
67+
}
68+
69+
//
70+
//
71+
//
72+
//
73+
//
74+
//
75+
//
76+
//
77+
//
78+
//
79+
//
80+
//
81+
82+
private static void coolStuffWithAString(String str) {
83+
System.out.println(
84+
str.toUpperCase()
85+
.trim()
86+
.replaceAll("S", "Z")
87+
.replaceAll("i", "i1Ii")
88+
);
89+
}
90+
91+
//
92+
//
93+
//
94+
//
95+
//
96+
//
97+
//
98+
//
99+
//
100+
//
101+
//
102+
//
103+
104+
/**
105+
* Hasta ahora hemos usado unicamente funciones estaticas pero existen algunos casos
106+
* en los que quisieramos usar un metodo de un objeto… porque tal vez el objeto ya
107+
* tiene un valor para operar, tiene alguna propiedad que puede ayudarnos en la operacion,
108+
* metodos que puedan ayudar a procesar los datos, etc.
109+
*/
110+
private void weirdStuff() {
111+
//Podemos usar directamente el paso de una funcion
112+
giveMeAFunction(stringParam -> stringParam.length());
113+
114+
//O usar una referencia a un metodo…
115+
//Lo interesante aqui es que Java se encarga de entender que `::length` va a
116+
//corresponder con el metodo ::length de lo que arriba definimos como `stringParam`
117+
//Es decir…
118+
//Java hace la conexion entre el objeto en memoria y hace la invocacion de su metodo
119+
//con el contexto del objeto en memoria…
120+
giveMeAFunction(String::length);
121+
//
122+
//
123+
//
124+
//
125+
//
126+
//
127+
//
128+
//
129+
//
130+
//
131+
//
132+
//
133+
//
134+
//
135+
136+
//Otro ejemplo de ello, es si nosotros tenemos un objeto totalmente ajeno
137+
//a las operaciones, pero este objeto tiene un metodo cuya definicion coincide
138+
//con la definicion de la funcion que necesitamos:
139+
140+
/*
141+
La clase tiene definido este metodo que recibe un string y devuelve un int.
142+
143+
144+
class HelperOperator {
145+
public int sayNameAge(String s){…}
146+
147+
}
148+
149+
150+
La funcion que tenemos que pasar, justamente, recibe un string y devuelve un int…
151+
152+
giveMeAFunction(Function<String, Integer> function)
153+
154+
155+
El match perfecto!
156+
*/
157+
HelperOperator sier = new HelperOperator("Sier");
158+
giveMeAFunction(sier::sayNameAge);
159+
}
160+
161+
//
162+
//
163+
//
164+
//
165+
//
166+
167+
private class HelperOperator {
168+
private String name;
169+
170+
public HelperOperator(String name) {
171+
this.name = name;
172+
}
173+
174+
public int sayNameAge(String s) {
175+
System.out.println("My name is " + name);
176+
return s.length();
177+
}
178+
}
179+
180+
181+
//
182+
//
183+
//
184+
//
185+
//
186+
//
187+
//
188+
//
189+
//
190+
//
191+
//
192+
193+
private static void giveMeAFunction(Function<String, Integer> function) {
194+
function.apply("Hello");
195+
}
196+
197+
//
198+
//
199+
//
200+
//
201+
//
202+
//
203+
//
204+
private static void howItWorks(){
205+
List<String> names = Utils.getListOf("Fer", "Orly", "Sinuhe", "Ana");
206+
207+
208+
209+
/*
210+
No solo es posible referenciar metodos de objetos o metodos estaticos,
211+
el operador :: en realidad se encarga de crear objetos sin que nosotros los
212+
tengamos que definir.
213+
214+
Es por eso que podemos asignar el resultado del operador en variables:
215+
*/
216+
Consumer<String> printer = _01_Operator::coolStuffWithAString;
217+
218+
219+
220+
221+
//Esto nos puede reducir las definiciones
222+
Consumer<String> outPrinter = s -> System.out.println(s);
223+
//Exactamente lo mismo que la linea de arriba
224+
Consumer<String> systemPrinter = System.out::println;
225+
226+
227+
228+
//Todas las invocaciones son valid
229+
names.forEach(printer);
230+
names.forEach(outPrinter);
231+
names.forEach(systemPrinter);
232+
}
233+
}

0 commit comments

Comments
 (0)