在进行流操作时,在中间/ pleleline操作期间,将创建具有不同特征的流(例如,SORTED / SIZED / DISTINCT / ORDERED) - 掌握Lambdas(第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
我们如何找出上述代码段中提到的流的不同特征?
答案 0 :(得分:10)
在每个阶段,您都可以致电:
int c = stream.spliterator().characteristics();
然后针对Spliterator类中定义的常量测试结果。例如,查看流是否已订购:
boolean isOrdered = (c & Spliterator.ORDERED) == Spliterator.ORDERED;
或者您也可以使用:
boolean isOrdered = stream.spliterator().hasCharacteristics(Spliterator.ORDERED);
答案 1 :(得分:9)
我想稍微扩展一下assylias所说的内容(绝对正确)。
首先,这些特征以普通int
实现,它是二进制表示。首先它全是零,但是当你添加某个特征时,它的位通过one
操作设置为OR
,通过AND
操作删除。
您可以通过以下方式查看某个Spliterator属性设置其one
的位置:
System.out.println(Integer.toBinaryString(Spliterator.SIZED)); // 1000000
它将右起第7位设置为1。所以当你检查:
Spliterator<Integer> spliterator = Stream.of(8, 3, 5, 6, 7, 4).spliterator();
System.out.println((spliterator.characteristics() & Spliterator.SIZED) == Spliterator.SIZED);
您实际上正在检查此特定位是否已设置。
<强>第二强>
有 4 流特征,这些特征被设置为第一个流创建的结果(而不是两个)。这本书有点过时,或者你没有向我们展示整个例子:
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
这些设置位(等于one
)对应SIZED
,ORDERED
,IMMUTABLE
,SUBSIZED
。
你所展示的其他人显然也略显偏离 - 你可以亲自检查一下。
第三次
这些特性在流处理中非常重要。几个例子:
long howMany = Stream.of(1, 2, 3).map(x -> {
System.out.println("mapping");
return x * 2;
}).count();
System.out.println(howMany); // 3
在java-9中,您不会看到mapping
已打印,因为您尚未更改流(您尚未清除SIZED
特征);因此根本不需要甚至评估映射。
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));
你会认为输出应该是false true
- 毕竟我们正在添加limit
,但是没有;结果是false false
:没有进行这样的优化,即使没有太多阻止它。