6

斯卡拉提供不可變的集合,例如SetListMap。我知道不變性在併發程序中有優勢。然而,正規數據處理中不可變性的優勢究竟是什麼?永恆集合的真正優勢是什麼?

如果我列舉例如subsets,permutationscombinations怎麼辦? 不可變的集合在這裏有什麼優勢嗎?

回答

10

定期數據處理中不可變性的優點究竟是什麼?

一般而言,不可變對象更容易/更簡單。

+3

狀態越少=分析越少。 –

+0

它使工具(即編譯器)能夠做更多的優化 – michid

+1

我同意,這意味着使用不可變對象會產生更經常正確的代碼。除了靜態類型外,這使得Scala代碼需要非常少的調試。 –

7

它的確如此。由於您正在枚舉集合,因此您可能想要確定在枚舉時不會無意中添加或刪除元素。

不變性是函數式編程中的一個範例。使集合不可變允許人們將它們想象得很像原始數據類型(即修改集合或任何其他對象導致創建不同的對象,就像添加2到3不會修改3,但創建5一樣)

+0

這是一個非常有趣的評論 - 它看起來像給你的數據上的「類似事務」的語義,也就是說如果你爲((k,v)< - myMap){something(k,v)})在'something'裏面'myMap + = k2 - > v2',你仍然會迭代當你啓動循環時'myMap'的快照。對?我從來沒想過那個。 –

4

如果你的數據在創建後不會改變,使用不可變的數據結構。您選擇的類型將標識使用的意圖。更具體的任何事情都需要知道你的特定問題空間。

您可能確實在尋找子集,排列或組合生成器,然後討論數據結構是沒有意義的。

另外,你提到你瞭解併發優勢。據推測,你在排列和子集上拋出了一些算法,並且算法在一定程度上可以並行化的可能性很大。如果是這樣的情況下,使用不可變的結構在前面,確保您最初的實現算法X將被很容易地轉換成並行算法X.

6

擴大馬特的答案:從我個人的經驗,我可以說,基於搜索樹算法實現(例如寬度優先,深度優先,回溯)使用可變集合定期作爲一堆垃圾:您可能忘記在遞歸調用之前複製集合,或者如果您收回集合,則無法正確收回更改。在那個領域,不變的收藏顯然是優越的。當我用Java的集合無法解決問題時,我最終用Java編寫了自己的不可變列表。瞧,第一個「不可變」的實施立即奏效。

+1

我希望你最近沒有寫過不可變的列表實現,因爲我們已經有了''Collections#unmodifiableList()'(Java SE)](http://download.oracle.com/javase/7/docs /api/java/util/Collections.html#unmodifiableList%28java.util.List%29)和['ImmutableList'(Google Guava)](http://docs.guava-libraries.googlecode.com/git-history/ v9.0/javadoc/com/google/common/collect/ImmutableList.html)一段時間。 –

+1

'unmodifiableList'完全沒有用,例如您無法獲得帶有額外元素的列表。番石榴很酷,但有時會過度殺傷。我知道的最好的不變列表實現來自http://functionaljava.org – Landei

2

我有幾個優點,添加到列表中:

  1. 不可變的集合不能從下你

    也就是說,這是完全罰款,有不可改變的公共VAL成員失效了一個Scala類。根據定義它們是隻讀的。與Java相比,您不僅需要記住使該成員保持私有狀態,還需要編寫一個返回對象副本的get方法,以便原始代碼不會被修改。

  2. 不可變的數據結構是持久的。這意味着通過調用TreeSet上的filter獲得的不可變集合實際上與原始節點共享其中的一些節點。這意味着節省時間和空間,並抵消使用不變性產生的一些懲罰。

0

一些不可改變的優勢:

1 - 小誤差餘量(你總是知道什麼是您的收藏和只讀變量)。

2 - 在修改變量和集合時,您可以編寫併發程序,而不用擔心線程之間相互踩踏。