一尘不染

如何正确找到Java-8中的流特征?

java

在执行流操作时,将在中间/流水线操作期间创建具有不同特征的流(例如:SORTED / SIZED / DISTINCT /
ORDERED)-掌握Lambda(第6章)

Stream.of(8,3,5,6,7,4) // ORDERED, SIZED
.filter(i->i%2==0) // ORDERED
.sorted() // ORDERED, SORTED
.distinct() // DISTINCT, ORDERED, SORTED
.map(i->i+1) // ORDERED
.unordered(); // none

我们如何找出上述片段中提到的流的不同特征?


阅读 307

收藏
2020-12-03

共1个答案

一尘不染

我想稍微延长一下亚述(绝对正确)。

首先 ,这些特征被实现为plain
int,它是二进制表示形式。首先是全零,但是当您添加某个特性时,one通过OR操作将该位设置为,通过该操作将其删除AND

您可以one通过执行以下操作简单地看到某个Spliterator属性在哪里设置它:

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)对应于SIZEDORDEREDIMMUTABLESUBSIZED

您显示的其他项目显然也略有偏离-您可以自己检查这些项目。

第三

这些特性在流处理中非常重要。一些例子:

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毕竟要添加a ,但不添加;结果是false false:即使没有太多阻止措施,也不会进行这种优化。

2020-12-03