根据 Spliterator#getComparator
的文档, 它指出
If this Spliterator's source is
SORTED
by aComparator
, returns thatComparator
. If the source isSORTED
in natural order, returns null. Otherwise, if the source is notSORTED
, throwsIllegalStateException
.Implementation Requirements:
The default implementation always throws
IllegalStateException
.Returns: a
Comparator
, ornull
if the elements are sorted in the natural order.Throws:
IllegalStateException
- if the spliterator does not report a characteristic ofSORTED
.
所以在运行这段代码的时候
Spliterator<Integer> spliterator = Stream.of(1, 2, 3).sorted().spliterator();
System.out.println((spliterator.characteristics() & Spliterator.SORTED) == Spliterator.SORTED);
System.out.println(spliterator.getComparator());
我得到:
true
null
到目前为止一切顺利。现在这样做:
Spliterator<Integer> spliterator = Stream.of(1, 2, 3).sorted(Comparator.naturalOrder()).spliterator();
System.out.println((spliterator.characteristics() & Spliterator.SORTED) == Spliterator.SORTED);
System.out.println(spliterator.getComparator());
它输出false
并抛出异常:
Exception in thread "main" java.lang.IllegalStateException
at java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.getComparator(StreamSpliterators.java:259)
at SpliteratorTest.main(SpliteratorTest.java:10)
为什么会输出false并抛出异常?
根据文档,它不应该给我提供给 sorted()
的 Comparator
吗?
(这也发生在 reverseOrder()
或 comparing(identity())
等中)。
最佳答案
内部流使用 StreamOpFlag
枚举,这与拆分器标志有些不同。使用 java.util.stream.StreamOpFlag.fromCharacteristics(Spliterator<?>)
方法转换标志,其实现如下:
static int fromCharacteristics(Spliterator<?> spliterator) {
int characteristics = spliterator.characteristics();
if ((characteristics & Spliterator.SORTED) != 0 && spliterator.getComparator() != null) {
// Do not propagate the SORTED characteristic if it does not correspond
// to a natural sort order
return characteristics & SPLITERATOR_CHARACTERISTICS_MASK & ~Spliterator.SORTED;
}
else {
return characteristics & SPLITERATOR_CHARACTERISTICS_MASK;
}
}
似乎流 API 不需要在内部没有明确自然排序的拆分器的 SORTED
特性,因此它没有保留。实际上,文档中从未指定 sorted(comparator).spliterator()
必须 返回具有 SORTED
特性的拆分器。 spliterator 文档说,如果它具有 SORTED
特性,则它必须返回比较器,但没有要求具有 SORTED
特性的情况,因此取决于实现。这在未来可能会改变,但这不是错误。
更新:刚刚注意到在 JDK-9 中,在 spliterator()
方法的文档中有一个明确的声明 added:
The returned spliterator should report the set of characteristics derived from the stream pipeline (namely the characteristics derived from the stream source spliterator and the intermediate operations). Implementations may report a sub-set of those characteristics. For example, it may be too expensive to compute the entire set for some or all possible stream pipelines.
查看 JDK-8048689 错误报告。
关于java - 从排序流中获取拆分器会引发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31159161/