Veo Get Vamos Lazy: Encuentre el poder real de los flujos de vídeo en youtube (Venkat Subramaniam). (minutos 26-30 aprox.)
En el ejemplo, un bucle for:
List<Integer> numbers = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
int result = 0;
for(int e: values){
if(e > 3 && e % 2 == 0){
result = e * 2;
break;
}
}
que tiene 8 "operaciones unitarias"
de acuerdo con su ejemplo:
public class MainClass {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
System.out.println(
numbers.stream()
.filter(e -> e > 3)
.filter(e -> e % 2 == 0)
.map(e -> e * 2)
.findFirst()
.orElse(0)
);
}
}
este código parece que tiene 21 "operaciones unitarias".
Y entonces se recomienda utilizar este código:
public class MainClass {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
System.out.println(
numbers.stream()
.filter(MainClass::isGT3)
.filter(MainClass::isEven)
.map(MainClass::doubleIt)
.findFirst()
.orElse(0)
);
}
private static int doubleIt(Integer e) {
return e * 2;
}
private static boolean isEven(Integer e) {
return e % 2 == 0;
}
private static boolean isGT3(Integer e) {
return e > 3;
}
}
Realmente quiero entender, ¿cómo se puede demostrado que tiene 8 unidades de operación en lugar de 21 operaciones de la unidad?
No no no, se entendió mal la idea. La idea es la evaluación perezosa de los arroyos. Y tanto se lleva "8" (cálculos utilizando sus palabras), trató de decir que parecía que se tardaría 21.
Esta
numbers.stream()
.filter(MainClass::isGT3)
.filter(MainClass::isEven)
.map(MainClass::doubleIt)
.findFirst()
.orElse(0)
Y
numbers.stream()
.filter(e -> e > 3)
.filter(e -> e % 2 == 0)
.map(e -> e * 2)
.findFirst()
.orElse(0)
Son exactamente lo mismo . La única diferencia es crear una función para ser más legibles y eso es todo. El código imperativo:
List<Integer> numbers = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
int result = 0;
for(int e: values){
if(e > 3 && e % 2 == 0){
result = e * 2;
break;
}
}
y el código en los arroyos, calcula exactamente el mismo, debido a que son llamados a la carta, significa que no filtra todos > 3
y el filtro de todo % 2 == 0
, que no, que combina que las operaciones, y luego aplicarlo cuando una función del terminal se llama ( como findFirst()
)
Como muestra el vídeo, si pones algunas impresiones entre las funciones, se mostrará las 8 operaciones:
public class Main {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
System.out.println(processStream(numbers));
System.out.println(getNumber(numbers));
System.out.println(getNumberEfficient(numbers));
}
static Stream<Integer> processStream(List<Integer> numbers){
return numbers.stream()
.filter(e -> {
System.out.println("GT3: " + e);
return e > 3;
})
.filter(e -> {
System.out.println("is Even: " + e);
return e % 2 == 0;
})
.map(e -> {
System.out.println("times 2: " + e);
return e * 2;
} );
}
static int getNumberEfficient(List<Integer> numbers){
return numbers.stream()
.filter(e -> {
System.out.println("GT3 and even: " + e);
return e > 3 && e % 2 == 0;
})
.map(e -> {
System.out.println("times 2: " + e);
return e * 2;
} )
.findFirst()
.orElse(0);
}
static int getNumber(List<Integer> numbers){
return numbers.stream()
.filter(e -> {
System.out.println("GT3: " + e);
return e > 3;
})
.filter(e -> {
System.out.println("is Even: " + e);
return e % 2 == 0;
})
.map(e -> {
System.out.println("times 2: " + e);
return e * 2;
} )
.findFirst()
.orElse(0);
}
}
devolverá:
Esta es la tubería, nada fue ejecutado, porque es Laze
java.util.stream.ReferencePipeline$3@7ba4f24f
Thees son las 8 operaciones:
GT3: 1
GT3: 2
GT3: 3
GT3: 5
is Even: 5
GT3: 4
is Even: 4
times 2: 4
8
Y esto es un poco de optimización, en vez de hacer dos filtros, se puede hacer sólo una, y reducir de 8 a 6:
GT3 and even: 1
GT3 and even: 2
GT3 and even: 3
GT3 and even: 5
GT3 and even: 4
times 2: 4
8