2017-07-03 54 views
0

我有下面的类:如何使一成不变的二维数组在斯卡拉

class Matrix(val matrix: Array[Array[Int]]) { 
// some other methods 
override def toString: String = { 
    return matrix.map(_.mkString(" ")).mkString("\n") 
    } 
} 

我宣布类变量val防止matrix进一步修改。

object Main { 
    def main(args: Array[String]) { 

    val > = Array 
    val x: Array[Array[Int]] = >(
     >(1, 2, 3), 
     >(4, 5, 6), 
     >(7, 8, 9)) 

    val m1 = new Matrix(x) 
    println("m1 -->\n" + m1) 
    x(1)(1) = 101 // Need to prevent this type of modification. 
    println("m1 -->\n" + m1) 
    } 
} 

x(1)(1) = 101后,程序的输出

m1 --> 
1 2 3 
4 101 6 
7 8 9 

但我想避免这种情况的修改,并得到原矩阵

m1 --> 
1 2 3 
4 5 6 
7 8 9 
+0

'val'不仅使变量不能被其他集合被重新分配,但你仍然可以在集合中重新分配领域 –

+0

你能告诉我如何防止这种修改? –

+0

使用不可变数据类型而不是可变数据类型。 'Array'是可变的(即使对它的引用不是)。您可以简单地使用'IndexedSeq'作为具有常量随机访问序列的通用特征。官方文件有一个关于馆藏及其特点的非常有趣的章节:http://docs.scala-lang.org/overviews/collections/overview.html – stefanobaghino

回答

0

有一个可变的之间的差异/不可变变量(例如var xval x)以及可变/不可变集合。声明一个(变量)不会影响其他(集合)。

Scala Array从Java继承而来,因此是可变的。有许多优秀的不可变收藏。 Array不是其中之一。

+0

这是一个矩阵的事实使我相信,有可能大量的随机访问。因此,内置的不可变集合的最佳选择是Vector。然而,看着Vector的代码,它看起来并不像Scala 2.12.2那样是专门的。这意味着所有的Ints将被包装的值,而不是4个字节的原语。我会建议编写更多的代码,以便使用适当的apply方法在Array [Array [Int]]周围创建一个不可变的包装器。如果您想就此方法提供完整的答案,请告诉我。 –

1

而不是使用数组的,也许你可以使用列表,而不是,这是不可改变的:

scala> val num:List[Int] = List(1,2,3) 
num: List[Int] = List(1, 2, 3) 

scala> num(1) = 3 
<console>:13: error: value update is not a member of List[Int] 
    num(1) = 3 
^
+0

我正在使用ListBuffer。你能告诉我如何将'scala.collection.mutable.ListBuffer [scala.collection.mutable.ListBuffer [Int]]'转换为'List [List [Int]]'? –

+0

'buff.map(_。toList).toList' – jwvh

+0

你真的不想要矩阵列表。他们可能会随机访问,所以这会带来很多开销。 –