首页 > 解决方案 > 如何避免可变集合的意外突变?

问题描述

所以,我写了一个代码来比较排序算法。我将一些算法实现为单独的类。为了解释起见,这里有一对夫妇。

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,现在可以使用。

标签: scala

解决方案


你传递了两次对同一个可变集合的引用ListBuffer。这意味着您的两种排序算法都将在同一个集合上工作,因此在第二次时,您的列表缓冲区将已经排序。

为避免意外突变,您只需在每次传递时创建一个防御性副本:

val input1 = new ListBuffer[Int]

//Populated input here

val input2 = input1.clone

val bs = new BubbleSort(input1)
val is = new InsertionSort(input2)

推荐阅读