scala - 如何避免可变集合的意外突变?
问题描述
所以,我写了一个代码来比较排序算法。我将一些算法实现为单独的类。为了解释起见,这里有一对夫妇。
class BubbleSort(input:ListBuffer[Int]){
...
}
class InsertionSort(input:ListBuffer[Int]){
...
}
从我的驱动程序对象中,我首先创建了一个列表,名为input
. BubbleSort
接下来,我将它传递给and的新实例InsertionSort
。然后我调用一个函数sort
,它对我在对象创建期间传递的 ListBuffer 进行排序。
val input = new ListBuffer[Int]
//Populated input here
val bs = new BubbleSort(input)
val is = new InsertionSort(input)
bs.sort
is.sort
我面临的问题是,当is.sort
被调用时,我在对象创建期间传递的列表已经排序。我想这是因为我先打了电话bs.sort
,但为什么它会影响另一个班级的列表?
任何帮助表示赞赏。如果你想要更多的代码片段,我很乐意分享。提前致谢!
编辑
作为临时修复,我没有只创建一个 list input
,而是使用样板代码并创建了两个列表,bsinput
并且isinput
. 然后将每个传递给单独的类。
val bsinput = new ListBuffer[Int]
val isinput = new ListBuffer[Int]
//Populated both arrays with the same data
val bs = new BubbleSort(bsinput)
val is = new InsertionSort(isinput)
bs.sort
is.sort
这解决了问题,但这是唯一的方法吗?有没有一种惯用的方式来做到这一点?
编辑 2
正如@LuisMiguelMejíaSuárez 所说,这是一个参考问题。使用过input.clone
,现在可以使用。
解决方案
你传递了两次对同一个可变集合的引用ListBuffer
。这意味着您的两种排序算法都将在同一个集合上工作,因此在第二次时,您的列表缓冲区将已经排序。
为避免意外突变,您只需在每次传递时创建一个防御性副本:
val input1 = new ListBuffer[Int]
//Populated input here
val input2 = input1.clone
val bs = new BubbleSort(input1)
val is = new InsertionSort(input2)
推荐阅读
- r - 使用R将数据集中的多列合并为一列
- mysql - 使用带有 LIKE 的 mysql 本机查询的 spring boot 搜索返回空
- java - 完成时转义字符的jline问题
- java - 如何添加 jar 文件来导入类?
- c# - WPF 在 Combobox 中设置启动值
- javascript - window.screenX 正在使用所有监视器进行计算,如何获取当前监视器中窗口的 x 位置
- wordpress - Wordpress Hosting 导入错误 Conflit Plugin Dokan
- java - 库损坏了类路径?
- c++ - C++ Webkit GTK,如何禁用跨源策略?
- dependency-injection - Angular 从 8 升级到 9,无法解析任何可注射的所有参数