ejemplo - procesamiento de datos con streams de java se 8-parte 2
¿Cómo encontrar correctamente las características de la secuencia en Java-8? (2)
En cada etapa puedes llamar:
int c = stream.spliterator().characteristics();
Y luego pruebe el resultado contra las constantes definidas en la clase Spliterator. Por ejemplo, para ver si la transmisión está ordenada:
boolean isOrdered = (c & Spliterator.ORDERED) == Spliterator.ORDERED;
Alternativamente puedes usar:
boolean isOrdered = stream.spliterator().hasCharacteristics(Spliterator.ORDERED);
Al hacer operaciones de flujo, durante las operaciones intermedias / lineales, las corrientes se crearían con diferentes características (por ejemplo, CLASIFICADO / TAMAÑO / DISTINTO / ORDENADO) - Dominando Lambdas (Canal 6)
Stream.of(8,3,5,6,7,4)//ORDERED, SIZED
.filer(i->i%2==0) // ORDERED
.sorted() // ORDERED, SORTED
.distinct() // DISTINCT, ORDERED, SORTED
.map(i->i+1) // ORDERED
.unordered(); //none
¿Cómo averiguamos las diferentes características de la transmisión como se menciona en el fragmento de arriba?
Me gustaría extender ligeramente lo que dijo assylias (que es absolutamente correcto).
Primero , estas características se implementan como plain int
, es representación binaria. Primero son todos ceros, pero cuando agrega una característica determinada, el bit se establece en one
través de la operación OR
, que se elimina mediante la operación AND
.
Puede ver dónde una determinada propiedad de Spliterator establece one
simplemente haciendo esto, por ejemplo:
System.out.println(Integer.toBinaryString(Spliterator.SIZED)); // 1000000
Está configurando el 7mo bit en uno desde la derecha. Entonces cuando marques:
Spliterator<Integer> spliterator = Stream.of(8, 3, 5, 6, 7, 4).spliterator();
System.out.println((spliterator.characteristics() & Spliterator.SIZED) == Spliterator.SIZED);
En realidad está comprobando si este bit en particular está configurado.
Segundo
Hay 4 características de flujo que se establecen como resultado de la creación de su primer flujo (y no dos). O el libro está un poco desactualizado o no nos has mostrado el ejemplo completo:
Spliterator<Integer> spliterator = Stream.of(8, 3, 5, 6, 7, 4).spliterator();
System.out.println(Integer.bitCount(spliterator.characteristics())); // 4
System.out.println(Integer.toBinaryString(spliterator.characteristics()));// 100010001010000
Estos bits de set (que son iguales a one
) corresponden a SUBSIZED
, SUBSIZED
, IMMUTABLE
, SUBSIZED
.
Los otros que has mostrado obviamente también están ligeramente apagados, puedes verificarlos tú mismo.
Tercero
Estas características son extremadamente importantes en el procesamiento de flujo. Algunos ejemplos:
long howMany = Stream.of(1, 2, 3).map(x -> {
System.out.println("mapping");
return x * 2;
}).count();
System.out.println(howMany); // 3
En java-9 no verá la mapping
impresa, porque no ha cambiado la secuencia (no ha borrado la característica SIZED
); por lo tanto, no es necesario evaluar el mapeo en absoluto.
Stream<Integer> unlimited = Stream.iterate(0, x -> x + 1);
System.out.println(unlimited.spliterator().hasCharacteristics(Spliterator.SIZED));
Stream<Integer> limited = unlimited.limit(3);
System.out.println(limited.spliterator().hasCharacteristics(Spliterator.SIZED));
Podrías pensar que el resultado debería ser false true
; estamos agregando un limit
después de todo, pero no; el resultado es false false
: no se realiza tal optimización, incluso si no hay mucho que lo impida.