5

The Stream interface has two overloads for the method of(). One of these is a variable-arity method while the other takes a single argument.

Is the single-argument method a performance optimization versus passing one argument to the variable-arity method? If so, how does it improve performance? The same questions could be asked of the empty() method, which would seem to be syntax sugar around the variable-arity of().

I see that the implementation differs between these methods, with the difference apparently being how the Spliterator is instantiated; but what advantage does this offer to the Stream API?

4

3 回答 3

6

空流和单元素流是非常常见的用例,尤其是当您使用.flatMap(). 例如,以下Optional.stream()是Java-9中的实现方式:

public Stream<T> stream() {
    if (!isPresent()) {
        return Stream.empty();
    } else {
        return Stream.of(value);
    }
}

因此,鉴于 Optionals 的流,您可以通过这种方式将它们展开到平面流中:

streamOfOptionals.flatMap(Optional::stream);

在这里,您创建了大量的空流以及单个元素流,因此优化此类情况看起来非常合理。特别是,like 不会创建空数组,也不会创建 spliterator(它重用相同的 spliterator 实例)Stream.empty()。在 内部也进行了特别优化,因此没有为单个元素分配数组。Stream.of()Stream.of(T)StreamBuilderImpl

于 2016-03-05T02:42:02.290 回答
5

是的,这是一种优化,可以避免创建一个仅包含单个元素的数组的开销,如果您使用 varargs 版本,您会得到这样的结果。

可以对 empty() 方法提出相同的问题,这似乎是围绕可变参数 of() 的语法糖

你在看什么实现版本?当我查看实现时,我看不到这一点。

于 2016-03-04T17:30:51.620 回答
1

我偶然发现了一个官方资源,它证实了这个问题的先前答案:JEP 269: Convenience Factory Methods for Collections。该提案的描述是,

List在、Set和接口上提供静态工厂方法,Map以创建这些集合的不可修改实例。

这些将包括可变参数重载,因此对集合大小没有固定限制......将提供最多十个元素的特殊情况 API(固定参数重载)。虽然这在 API 中引入了一些混乱,但它避免了由 varargs 调用引起的数组分配、初始化和垃圾收集开销。

所以性能优化很简单,就是避免使用 varargs 方法的数组。

于 2016-03-14T00:23:18.757 回答