2015-02-24 36 views

回答

4

恐怕不行,但可以改善這個代碼的可讀性構建

Stream.generate(source).limit(size).collect(Collectors.toList()) 

雖然作爲Brian Goetzmentioned您的原始版本將並行好得多。

+0

在另一方面,示例(使用IntStream.range)會使_much_更好地並行化。 – 2015-02-25 15:40:58

+0

@BrianGoetz這非常有趣。你可以添加一些關於這個主題的更多信息(也許鏈接)? – Pshemo 2015-02-25 15:48:43

+2

limit()操作的語義與遇到順序有關,並且這種耦合成爲對並行性的重要限制。作爲一個例子,設想實現並行的'findFirst'和'findAny';應該很清楚,後者會並行化得更好(因爲一旦找到答案,就不必等待所有早期元素完成)。另一方面,範圍完美分割,因此工作將乾淨地分配跨核心。 – 2015-02-25 16:13:21

2

這裏的另一種變化:

static <T> List<T> listFromFunc(int size, Supplier<T> source) { 
    return Collections.nCopies(size, "").stream() 
     .map(o -> source.get()) 
     .collect(Collectors.toCollection(() -> new ArrayList<>(size))); 
} 

這使流是SIZED貫穿始終。 Collections.nCopies().stream()實際上在內部使用IntStream.range(),所以它不會更快或什麼,但。

使用Collectors.toCollection()可以控制列表的具體類型,toList()不是。在順序情況下,這還允許您預先設置列表的大小,避免元素添加到列表時可能發生的複製。

(公平的警告:在JDK 8,toList()創建一個ArrayList,但我們可能會在JDK 9更改爲返回一個列表類型更適合於追加。)在這個問題

+1

或'Collections.nCopies(size,source).stream()。map(Supplier :: get)'... – Holger 2015-02-25 09:10:52

+0

@Holger Ha!是的,非常有趣的變化! – 2015-02-25 18:33:47

相關問題