9
Why are Java Streams once-off? - Stack Overflow (stackoverflow.com)
IngramChen 積分 5

真是不錯的問答,有原工作人員出來說明來龍去脈才能了解為什麼 Java 多了另一個很像 Iterable 的 Stream。

一切都是舊時代的包袱啊

自從去年轉到 Java8 之後,我的程式到處都充滿了 Stream,我看其他的 Java8 使用者也是如此,根本就回不去 for loop 了。我想三、四年後大部份的 Java 開發者會逐漸接受 functional programming style。

Stream 只能用一次,有什麼問題嗎?在實務上,我有幾次會想要重用 Stream,但無奈不支援,所以把它 collect()List 再使用 (通常在 DAO 裡)。但是這樣的例子實在是不多,而且很簡單就能解決。看了這個問答才讓我了解到原來為了避開 讓開發者 surprise ,Stream 才脫離 Iterable,長成現在這個樣子。

另一件事就是使用 Stream 時實務上容易有 Bug 嗎 ? 現在要我想起來運用 Stream 時有產生什麼 bug 我還真的想不起來,即使已經寫了一年了。bug rate 很低啊這。用起來就是物件在中間一直轉轉轉的,很順手。這種 隱性 的功能完全是靠設計者們的功力和心力了。

Stream 到底有沒有難用,容易有 bug 的地方?還是有啦,就是使用 Parrelell Stream 時充滿了驚奇 (壞的意味),Parrelell 真是難駕馭的怪獸,結果通常不是自己想要的 (包含運算結果和效能...),我現在只能在 unit test 時用一用。還好平行運算不是日常開發會遇到的工作,這個缺點還不算太嚴重。

從實戰的角度來看,Java 8 Stream 的設計人做了一些妥協,而這個妥協滿足了大部份的需求 (就我來看是 95:5 的比例,只有 5 % 會想要重用 Stream),Bug 也少,這算是很成功的設計。當然啦,如果 Java 第一天就俱備 lazy evaluation functional programming 概念,我們會看到更完美的設計,就像 Dart 一樣,而不是現在 CollectionIterableIteratorStream 等類似的概念在衝突。

HYL 積分 3

做成 one-off 比較好啊,在 Scala Stream 是 lazy memorization collection ,我們最近一個月就踩到了兩次問題,造成 OutOfMemoryError

val stream = (1 to 10000).toStream  
   .map(id => dao.find(id))  // 1
   .flatMap(_.getOptionalInt) // 2
   .filter(_ < 10) // 3
   .foldLeft(0)((ret, a) => ret + a)

這看起來是把一萬個 object ,取出其中的一個 Int 參數,過濾掉小於 10 的數值,再一個個取出來相加,並不會造成太大的的計憶體負擔,但實際上卻生成了 1, 2, 3 個各有一萬個 object 的 Stream

一不小心,就丟 OutOfMemoryError 了

IngramChen 積分 0

中間都會自己做一份 copy 啊,scala 這樣子,怎麼會適用在 big data 上呢? (spark...)

還是 spark 裡的 scala stream 重新寫過了?

HYL 積分 1

Spark 不知道,但是 scoobi (scala framework for Hadoop) 就是自己重做了一份。

scalaz 也弄了自己的 EphemeralStream

kaif 積分 1 編輯於

對我來說最大的問題就是看java doc還是不會用xd 要用背的或剪貼code。很難想像之後scjp納入stream以後考題會長怎樣

IngramChen 積分 2

是指 collect 的後半那一段吧? 那的確很難。不過我覺得那個跟學 SQL 時的感覺很像,你就是大概知道怎麼用,不過複雜一點的就要試幾次才會對,而且很多時候都要找範例來看。

qrtt1 積分 1

雖然還沒寫 java 8。但會寫 groovy 有 closure 經驗,也用過 spark(設計得有像 stream api),單純看起來可以接受

IngramChen 積分 0

咬著牙硬升級吧 XD