如何避免可变集合的意外突变?

时间:2019-05-06 20:29:09

标签: scala

因此,我编写了一个代码来比较排序算法。我将几个algs作为单独的类实现。这是出于解释的原因。

class BubbleSort(input:ListBuffer[Int]){
...
}

class InsertionSort(input:ListBuffer[Int]){
...
}

首先从驱动程序对象中创建一个名为input的列表。 接下来,我将其传递给BubbleSortInsertionSort的新实例。 然后,我调用函数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,但是为什么它会影响另一个类中的列表?

感谢您的帮助。如果您需要更多代码段,我将很高兴与您分享。提前致谢!

编辑 作为临时解决方案,我不再创建一个列表input,而是使用样板代码并创建了两个列表bsinputisinput。然后每个都传递到单独的类。

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

1 个答案:

答案 0 :(得分:1)

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

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

val input1 = new ListBuffer[Int]

//Populated input here

val input2 = input1.clone

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