Comment trouver correctement les caractéristiques du flux dans Java-8?


Lors des opérations de flux, pendant les opérations intermédiaires/pipleline, les flux seraient créés avec des caractéristiques différentes (par exemple TRIÉS/DIMENSIONNÉS/DISTINCTS/ORDONNÉS) - Mastering Lambdas (Ch 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

Comment déterminer les différentes caractéristiques des flux comme mentionné dans l'extrait ci-dessus?

Author: Stefan Zobel, 2017-06-11

2 answers

Je voudrais étendre légèrement ce qu'assylias a dit (ce qui est absolument correct).

Tout d'abord, ces caractéristiques sont implémentées en tant que int simple, c'est une représentation binaire. Tout d'abord, ce sont tous des zéros, mais lorsque vous ajoutez une certaine caractéristique, son bit est défini sur one via l'opération OR, supprimé via l'opération AND.

Vous pouvez voir où une certaine propriété Spliterator définit son one simplement en faisant ceci par exemple:

System.out.println(Integer.toBinaryString(Spliterator.SIZED)); // 1000000

C'est le réglage le 7-bit bit dans un de la droite. Donc, lorsque vous vérifiez:

Spliterator<Integer> spliterator = Stream.of(8, 3, 5, 6, 7, 4).spliterator();
System.out.println((spliterator.characteristics() & Spliterator.SIZED) == Spliterator.SIZED);

Vous vérifiez en fait si ce bit particulier est défini.

Deuxième

Il y a 4 caractéristiques de flux définies à la suite de la création de votre premier flux(et non de deux). Soit le livre est un peu dépassé, soit vous ne nous avez pas montré l'exemple entier:

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

Ces bits (qui sont égal à one) correspondent à SIZED, ORDERED, IMMUTABLE, SUBSIZED.

Les autres que vous avez montrés sont évidemment légèrement décalés aussi - vous pouvez les vérifier vous-même.

Troisième

Ces caractéristiques sont extrêmement importantes dans le traitement des flux. Quelques exemples:

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, vous ne verrez pas le mapping imprimé, car vous n'avez pas changé le flux (vous n'avez pas effacé la caractéristique SIZED); donc pas besoin d'évaluer même le mappage du tout.

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));

On pourrait penser que le la sortie devrait être false true - nous ajoutons un limit après tout, mais non; le résultat est false false: aucune optimisation de ce type n'est faite, même s'il n'y a pas grand-chose qui l'empêche.

 9
Author: Eugene, 2017-06-11 20:42:11

, À chaque étape, vous pouvez appeler:

int c = stream.spliterator().characteristics();

Puis testez le résultat par rapport aux constantes définies dans la classe Spliterator. Par exemple pour voir si le flux est ordonné:

boolean isOrdered = (c & Spliterator.ORDERED) == Spliterator.ORDERED;

Vous pouvez également utiliser:

boolean isOrdered = stream.spliterator().hasCharacteristics(Spliterator.ORDERED);
 10
Author: assylias, 2017-06-11 17:09:23