我想稍微扩展一下assylias所说的(这是绝对正确的)。
首先,这些特征被实现为普通的,它是二进制表示。首先,它都是零,但是当您添加某个特征时,它的位通过操作设置为,通过操作删除。int
one
OR
AND
您可以看到某个 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
这些集合位(等于 )对应于 、 、 、 。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