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

2022-09-03 06:20:32

在执行流操作时,在中间/管道操作期间,将创建具有不同特征的流(例如:排序/大小/不同/有序) - 掌握 Lambdas(第 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

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


答案 1

在每个阶段,您可以调用:

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

然后根据 Spliterator 类中定义的常量测试结果。例如,查看流是否排序:

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

或者,您可以使用:

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

答案 2

我想稍微扩展一下assylias所说的(这是绝对正确的)。

首先,这些特征被实现为普通的,它是二进制表示。首先,它都是零,但是当您添加某个特征时,它的位通过操作设置为,通过操作删除。intoneORAND

您可以看到某个 Spliterator 属性设置它的位置,只需执行此操作,例如:one

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

它将第 7 位设置为从右侧开始的位。因此,当您检查时:

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

这些集合位(等于 )对应于 、 、 、 。oneSIZEDORDEREDIMMUTABLESUBSIZED

您展示的其他内容显然也略有不同 - 您可以自己检查这些内容。

第三

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

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

在java-9中,您将看不到打印的,因为您尚未更改流(您尚未清除特征);因此,甚至根本不需要评估映射。mappingSIZED

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 truelimitfalse false


推荐