【发布时间】:2025-11-27 19:00:01
【问题描述】:
我正在研究来自 guava 的 Streams::findLast 的实现,在尝试理解它的同时,有几件事我根本无法理解。这是它的实现:
public static <T> java.util.Optional<T> findLast(Stream<T> stream) {
class OptionalState {
boolean set = false;
T value = null;
void set(@Nullable T value) {
set = true;
this.value = value;
}
T get() {
checkState(set);
return value;
}
}
OptionalState state = new OptionalState();
Deque<Spliterator<T>> splits = new ArrayDeque<>();
splits.addLast(stream.spliterator());
while (!splits.isEmpty()) {
Spliterator<T> spliterator = splits.removeLast();
if (spliterator.getExactSizeIfKnown() == 0) {
continue; // drop this split
}
// Many spliterators will have trySplits that are SUBSIZED even if they are not themselves
// SUBSIZED.
if (spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
// we can drill down to exactly the smallest nonempty spliterator
while (true) {
Spliterator<T> prefix = spliterator.trySplit();
if (prefix == null || prefix.getExactSizeIfKnown() == 0) {
break;
} else if (spliterator.getExactSizeIfKnown() == 0) {
spliterator = prefix;
break;
}
}
// spliterator is known to be nonempty now
spliterator.forEachRemaining(state::set);
return java.util.Optional.of(state.get());
}
Spliterator<T> prefix = spliterator.trySplit();
if (prefix == null || prefix.getExactSizeIfKnown() == 0) {
// we can't split this any further
spliterator.forEachRemaining(state::set);
if (state.set) {
return java.util.Optional.of(state.get());
}
// fall back to the last split
continue;
}
splits.addLast(prefix);
splits.addLast(spliterator);
}
return java.util.Optional.empty();
}
老实说,从本质上讲,实现并不是那么复杂,但这里有一些我觉得有点奇怪的事情(如果这个问题被关闭为“基于意见”,我会在这里承担责任,我理解可能发生)。
首先是创建OptionalState 类,这可以替换为单个元素的数组:
T[] state = (T[]) new Object[1];
使用起来很简单:
spliterator.forEachRemaining(x -> state[0] = x);
那么整个方法可以拆分成3个部分:
1) 当某个Spliterator已知为空时:
if (spliterator.getExactSizeIfKnown() == 0)
在这种情况下,这很容易 - 只需放下它。
2) 如果知道 Spliterator 是 SUBSIZED。这是“快乐路径”场景;在这种情况下,我们可以拆分它,直到我们到达最后一个元素。基本上,实现说:拆分直到prefix 为null 或者它为空(在这种情况下使用“正确”拆分器),或者如果拆分后已知“正确”拆分器为空,则使用@987654330 @ 一。这是通过:
// spliterator is known to be nonempty now
spliterator.forEachRemaining(state::set);
return java.util.Optional.of(state.get());
第二个问题其实是关于这条评论的:
// Many spliterators will have trySplits that are SUBSIZED
// even if they are not themselves SUBSIZED.
这很有趣,但我找不到这样的例子,如果有人能给我介绍一个,我将不胜感激。事实上,因为这个注释的存在,接下来的代码(方法的第三部分不能像第二个那样用while(true)来完成),因为它假设在trySplit之后我们可以获得Spliterator即SUBSIZED,即使我们最初的不是,所以它必须到findLast的最开始。
3) 这部分方法是当一个Spliterator已知不是SUBSIZED并且在这种情况下它没有已知的大小;因此它依赖于源中的 Spliterator 是如何实现的,在这种情况下,实际上 findLast 没有什么意义......例如,来自 HashSet 的 Spliterator 将返回最后一个存储桶中的最后一个条目。 ..
【问题讨论】:
标签: java java-8 java-stream guava