2017-06-11 3 views
13

Während Stream-Operationen zu tun, während der Zwischen-/pipleline Operationen die Ströme mit unterschiedlichen Merkmalen geschaffen würden (zB SORTED/SIZED/DISTINCT/BESTELLT) - Mastering Lambdas (Ch 6)Wie finde ich die Stream-Eigenschaften in Java-8 richtig?

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 

Wie finden wir heraus, die verschiedenen Eigenschaften des Streams, wie im obigen Snippet erwähnt?

Antwort

8

Ich mag etwas würde verlängern, was assylias sagte (was absolut richtig ist).

Zuerst, diese Eigenschaften werden als einfache int implementiert, es ist binäre Darstellung. Zuerst sind es nur Nullen, aber wenn Sie ein bestimmtes Merkmal hinzufügen, wird das Bit auf one über die Operation OR gesetzt und über die Operation AND entfernt.

können Sie sehen, wo eine bestimmte Spliterator Eigenschaft, indem Sie diese zum Beispiel seine one setzt einfach:

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

Es ist die 7-te Bit in einer von rechts zu setzen. Also, wenn Sie überprüfen:

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

Du bist gerade eigentlich, wenn diese insbesondere Bit gesetzt ist.

Zweite

Es gibt Strom Merkmale, die als Ergebnis der ersten Stroms Schöpfung gesetzt werden (und nicht zwei). Entweder ist das Buch ein bisschen veraltet oder Sie haben nicht zeigte uns das gesamte Beispiel:

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 

Diese gesetzten Bits (die zu one gleich sind) entsprechen SIZED, ORDERED, IMMUTABLE, SUBSIZED.

Die anderen, die Sie gezeigt haben, sind offensichtlich auch etwas daneben - Sie können diese selbst überprüfen.

Dritte

Diese Eigenschaften sind sehr wichtig in Stream-Verarbeitung.Einige Beispiele:

long howMany = Stream.of(1, 2, 3).map(x -> { 
     System.out.println("mapping"); 
     return x * 2; 
    }).count(); 
    System.out.println(howMany); // 3 

in Java-9 wird der mapping gedruckt nicht sehen, da man nicht den Strom verändert haben (man die SIZED Merkmal nicht deaktiviert haben); Daher muss das Mapping überhaupt nicht bewertet werden.

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

Sie würden denken, dass die Ausgabe false true sein sollte - wir limit schließlich hinzufügen, aber nicht; Das Ergebnis ist false false: keine solche Optimierung wird durchgeführt, auch wenn es nicht viel verhindert.

+0

Nein, ich habe das ganze Snippet gegeben. Vielleicht habe ich veraltete Ausgabe des Buches. –

+0

Drittes Beispiel (das zweite Snippet), kümmert sich jdk9 nicht darum ?? –

9

Auf jeder Stufe können Sie anrufen:

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

Und dann testen Sie das Ergebnis anhand der definierten Konstanten in der Spliterator Klasse. Zum Beispiel, um zu sehen, ob der Strom bestellt:

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

Alternativ können Sie verwenden:

boolean isOrdered = stream.spliterator().hasCharacteristics(Spliterator.ORDERED); 
+0

Sie können das nicht * in jeder Phase *, der Stream würde verbraucht werden ... – Eugene

+3

@Eugene: Sie können den Stream vom Spliterator neu erstellen, [siehe hier] (https://stackoverflow.com/a/28475289/2711488), nehme ich an, das ist, was das OP ist nach ... – Holger

+2

@Holger ah! das würde Sinn machen, einen Stream von diesem Spliterator zurückzugeben ... thx. aufrichtige Gratulation an die 100k. – Eugene