5

Stream接口对于方法of()有两个过载。其中一个是可变参数方法,而另一个则采用单一参数。为什么在Java Stream接口中重载()的varargs方法?

单参数方法是一个性能优化与将一个参数传递给变量arity方法吗?如果是这样,它如何提高性能?可能会询问empty()方法的相同问题,这似乎是可变参数of()附近的语法糖。

我看到这些方法之间的实现不同,显然不同之处在于Spliterator是如何实例化的;但是这对Stream API有什么优势?

回答

5

是的,这是一个优化,以避免创建一个数组只保留一个元素的开销,这是你使用可变参数版本时得到的结果。

同样的问题也可以问空()方法,这似乎左右的()

执行什么版本的变元数你在看语法糖?当我看到实现时,我没有看到这一点。

+0

我的意思只是方法签名似乎表明语法糖(文档没有指向某种方式或其他方式)。我看到实现是不同的。 – jaco0646

+0

避免单元素或空数组看起来像是一个微优化。这是普通开发者应该关注的事情吗?我应该为所有可变参数方法提供这种类型的性能优化吗? – jaco0646

+1

@ jaco0646,语法糖有什么问题?特别是如果它也提供性能优化机会。 –

5

空流和单元素流是非常常见的用例,尤其是当您使用.flatMap()时。例如,这里是如何Optional.stream()是Java-9 implemented

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

因此,考虑选配流,你可以解开他们进入平板流是这样的:

streamOfOptionals.flatMap(Optional::stream); 

在这里,你创建吨的空流以及单个元素流,因此优化这些情况看起来非常合理。特别是,Stream.empty()Stream.of()不同,它不会创建一个空数组,并且不会创建分割器(它将重新使用相同的分割器实例)。 Stream.of(T)也在StreamBuilderImpl内特别优化,所以没有数组被分配给单个元素。

1

我偶然发现了一个确认此问题的以前的答案的官方资源:JEP 269: Convenience Factory Methods for Collections。该提案的说明是,

提供了创建这些集合的不可修改的情况下,对ListSet,并Map接口的静态工厂方法。

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

因此,性能优化很简单,以避免可变参数方法的数组。

相关问题