首页 > 解决方案 > 为什么流的方法没有在 java api 中声明为默认值?

问题描述

我是流的新手,据我所知,这会返回一个流:

IntStream.range(0, 20).skip(10)

IntStream 是一个接口,在 java api 的默认部分中有这个:

static IntStream range(int startInclusive,
                       int endExclusive)

然而,

IntStream skip(long n)

没有显示在 java api 中被声明为默认值,即使它显然有一个实现。

有人可以详细说明为什么吗?

标签: javamethodsinterfacejava-stream

解决方案


我想你误会了。IntStream是一个接口。因此,实际的实现取决于......无论什么类决定implements IntStream在它的末尾加上一个。这样的类称为“IntStream 实现”。IntStream 实现可以自由地实现 skip 方法和 int 流的整个概念,以任何它想要的方式。

问题是你不能说IntStream 的实现skip。您只能说IntStream的实现skip。将 skip 的某些实现硬编码为默认实现会很奇怪,特别是考虑到您无法编写它:无论 IntStream 如何工作,您将如何实现适用于任何 IntStream 的 skip 方法?

默认实现通常被设计为与其他(非默认)方法一起使用作为基本构建块。比如java 8在java.util.Map(是一个接口)中添加了下面的方法:getOrDefault(Object key, V defaultValue),它是按照map的get方法和map的containsKey方法来实现的,两者都没有默认实现(它们是积木;要成为一个map,你有实施这些)。

那些基本的构建块?那些没有默认实现;这就是重点:此类接口的实现需要提供每个此类构建块方法的实现,其余方法(默认方法)将根据这些构建块正常工作,但如果您也想实现这些,例如,因为您可以更有效地做到这一点,请随意。

这留下了最后一个问题:是skip“构建块”或更复杂的“构建在构建块上”的方法吗?作者认为它是一个构建块,并且通过一次读取一个元素并丢弃它们直到 X 元素被丢弃来实现它,感觉太明显了。

他们为什么做出这样的选择?你得问问作者,据我所知,这种详细的讨论在公开辩论中是没有涉及的,你可以在诸如lambda-dev 之类的邮件列表中关注这些讨论。

注意:range您提到的方法是静态的。静态方法就像命名构造函数:该方法根本不需要上下文或现有流:相反,它创建一个新IntStream的流过范围的流。它产生一个特定的IntStream接口实现;许多其他存在,并且它的实现skip方式不一定适用于其他内部流实现。


推荐阅读