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中引入了一些混亂,但它避免了由可變參數調用引起的數組分配,初始化和垃圾收集開銷。

因此,性能優化很簡單,以避免可變參數方法的數組。

相關問題