Scala中向多个方法传递同一数组数据的问题求解
问题原因与解决方案
你遇到的问题核心是Scala中数组是可变的引用类型——当你把array传递给One和Two方法时,传递的不是数组的副本,而是指向原始数组内存地址的引用。第一个方法One里直接修改了数组元素(比如arr(i)(1) -= q、arr(i)(1) = 0这些操作),这些修改会直接作用在原始数组上,等调用Two方法时,自然拿到的是已经被改得面目全非的数组了。
要让两个方法都拿到原始的同一组数据,你需要给每个方法传递原始数组的深拷贝,确保它们操作的是独立的副本,互不干扰。
具体实现步骤
因为你用的是二维数组,普通的clone()只能做浅拷贝(外层数组是新的,但内层的每个小数组还是引用原始数据),所以需要做深拷贝:
方案1:在调用方法时传递拷贝后的数组
修改main方法里的调用逻辑,给每个方法传递独立的深拷贝:
object Demo { def main(args: Array[String]): Unit = { println("Enter number of process:"); val n = scala.io.StdIn.readInt(); var array: Array[Array[Double]] = Array.ofDim(n, 2) var bt: Double = 0 var at: Double = 0 for (i <- 0 to n - 1) { println("Enter BT for process: " + i); bt = scala.io.StdIn.readDouble(); println("Enter AT for process: " + i); at = scala.io.StdIn.readDouble(); array(i)(0) = at array(i)(1) = bt } // 给One方法传递深拷贝 One(n, array.map(_.clone())) // 给Two方法传递深拷贝(基于原始array) Two(n, array.map(_.clone())) } // 下面的One和Two方法保持原样即可 def One(n: Int, data: Array[Array[Double]]): Unit = { var q = 0.0 var arr = data arr = arr.sortBy(x => x(1)) var arr_copy = arr var wt = new Array[Double](n) var a = new Array[Double](n) var tat = new Array[Double](n) var new_tat = new Array[Double](n) var new_wt = new Array[Double](n) var D_Sum = 0.0 var sum = 0.0 for (i <- 0 to n - 1) { a(i) = arr(i)(1) } for (i <- 0 to n - 1) { wt(i) = 0 } var tracker = 0.0 var li = 0 var updated_TAT = 0.0 do { D_Sum = 0.0 arr = arr.filterNot(x => x(1) <= 0) for (i <- 0 to arr.size - 1) { D_Sum = D_Sum + arr(i)(1) } q = math.round(math.sqrt(arr.length * D_Sum * 1.49)) for (i <- 0 to arr.size - 1) { if (tracker >= arr(i)(0)) { if (arr(i)(1) > q) { arr(i)(1) -= q tracker = tracker + q for (j <- 0 to arr.size - 1) { if ((j != i) && (arr(j)(1) != 0)) wt(j) += q } } else { for (j <- 0 to arr.size - 1) { if ((j != i) && (arr(j)(1) != 0)) { wt(j) += arr(i)(1) } } tracker = tracker + arr(i)(1) updated_TAT = tracker new_tat(li) = updated_TAT - arr_copy(i)(0) new_wt(li) = tracker - arr_copy(i)(1) - arr_copy(i)(0) li = li + 1 arr(i)(1) = 0 } } } sum = 0.0 for (i <- 0 to arr.length - 1) sum = sum + arr(i)(1) } while (sum != 0) var avg_wt = 0.0 var avg_tat = 0.0 for (j <- 0 to n - 1) avg_wt += wt(j) for (j <- 0 to n - 1) avg_tat += new_tat(j) println("average waiting time= " + (avg_wt / n) + " Average turn around time= " + (avg_tat / n)) } def Two(n: Int, data: Array[Array[Double]]): Unit = { var arr = data arr = arr.sortBy(x => x(1)) var arr_copy = arr var q = 0.0 var wt = new Array[Double](n) var a = new Array[Double](n) var tat = new Array[Double](n) var new_tat = new Array[Double](n) var new_wt = new Array[Double](n) var sum = 0.0 for (i <- 0 to n - 1) { a(i) = arr(i)(1) } for (i <- 0 to n - 1) { wt(i) = 0 } var tracker = 0.0 var li = 0 var updated_TAT = 0.0 do { arr = arr.filterNot(x => x(1) <= 0) q = arr(0)(1) for (i <- 0 to arr.size - 1) { if (tracker >= arr(i)(0)) { if (arr(i)(1) > q) { arr(i)(1) -= q tracker = tracker + q for (j <- 0 to arr.size - 1) { if ((j != i) && (arr(j)(1) != 0)) wt(j) += q } } else { for (j <- 0 to arr.size - 1) { if ((j != i) && (arr(j)(1) != 0)) { wt(j) += arr(i)(1) } } tracker = tracker + arr(i)(1) updated_TAT = tracker new_tat(li) = updated_TAT - arr_copy(i)(0) new_wt(li) = tracker - arr_copy(i)(1) - arr_copy(i)(0) li = li + 1 arr(i)(1) = 0 } } } sum = 0.0 for (i <- 0 to arr.length - 1) sum = sum + arr(i)(1) } while (sum != 0) var avg_wt = 0.0 var avg_tat = 0.0 for (j <- 0 to n - 1) avg_wt += wt(j) for (j <- 0 to n - 1) avg_tat += new_tat(j) println("average waiting time= " + (avg_wt / n) + " Average turn around time= " + (avg_tat / n)) } }
方案2:在方法内部先拷贝数据
如果你不想修改调用逻辑,也可以在One和Two方法的开头,先对传入的data做深拷贝,确保方法内部操作的是副本:
def One(n: Int, data: Array[Array[Double]]): Unit = { // 先做深拷贝,后续操作这个副本 val arr = data.map(_.clone()) // 下面的代码用arr代替原来的data,其他逻辑不变 // ... 原方法剩余代码 ... } def Two(n: Int, data: Array[Array[Double]]): Unit = { val arr = data.map(_.clone()) // ... 原方法剩余代码 ... }
关键说明
array.map(_.clone())是二维数组的深拷贝方式:外层数组用map生成新数组,每个内层小数组用clone()生成独立副本,这样整个二维数组的元素都是独立的,修改副本不会影响原始数组。- 这样修改后,
One和Two方法都会拿到和原始输入完全一致的初始数据,各自的修改只会作用在自己的副本上,不会互相干扰。
内容的提问来源于stack exchange,提问作者asif
相关产品推荐
相关产品推荐

