Scala提供不可变集合,例如Set
,List
,Map
。我知道不变性在并发程序中具有优势。然而,常规数据处理中不变性的优势究竟是什么?
如果我列举subsets
,permutations
和combinations
,该怎么办? immutable 集合在这里有什么优势吗?
答案 0 :(得分:10)
常规数据处理中不变性的优势是什么?
一般来说,不可变对象更容易/更容易推理。
答案 1 :(得分:7)
确实如此。由于您在枚举上进行了枚举,因此您可能希望确定在枚举时不会无意中添加或删除元素。
不可变性在函数式编程中是一种范式。使集合不可变允许人们将它们视为原始数据类型(即修改集合或任何其他对象导致创建不同的对象,就像添加2到3不会修改3,但创建5)
答案 2 :(得分:6)
扩展Matt的答案:根据我的个人经验,我可以说基于搜索树的算法实现(例如广度优先,深度优先,回溯)使用可变集合最终定期作为一堆热气腾腾的废话:要么你忘记了在递归调用之前复制集合,或者如果收回集合,则无法正确地收回更改。在那个领域,不可变的收藏显然是优越的。当我无法正确使用Java的集合时,我最终用Java编写了自己的不可变列表。瞧,第一个“不可改变”的实施立即起作用。
答案 3 :(得分:4)
如果您的数据在创建后没有更改,请使用不可变数据结构。您选择的类型将标识使用意图。任何更具体的内容都需要了解您的特定问题空间。
您可能真的在寻找子集,置换或组合生成器,然后对数据结构的讨论没有实际意义。
另外,您提到您了解并发优势。据推测,您在排列和子集中抛出了一些算法,并且算法很可能在某种程度上并行化。如果是这种情况,预先使用不可变结构可确保算法X的初始实现很容易转换为并发算法X.
答案 4 :(得分:2)
我有一些优势可以添加到列表中:
无法从您下面无效收集
也就是说,拥有Scala类的不可变公共val成员是完全没问题的。根据定义,它们是只读的。与Java相比,您不仅要记住将成员设为私有,还要编写一个get
方法,该方法返回对象的副本,以便原始代码不会被调用代码修改。
不可变数据结构是持久的。这意味着通过调用filter
上的TreeSet
获得的不可变集合实际上与原始节点共享其部分节点。这可以节省时间和空间,并抵消因使用不变性而产生的一些处罚。
答案 5 :(得分:0)
一些不变性优势:
1 - 错误的较小余量(您始终知道集合和只读变量中的内容)。
2 - 你可以编写并发程序,而不必担心在修改变量和集合时线程互相踩踏。