2017-07-03 2 views
0

Ich habe die folgende Klasse machen:Wie unveränderlich 2D Array in Scala

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

I Klasse Variable deklariert haben als val in matrix weitere Modifikation zu verhindern.

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) 
    } 
} 

Nach x(1)(1) = 101 tun die Ausgabe des Programms ist

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

Aber ich will diese Änderung verhindern und die ursprüngliche Matrix als

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

'val' macht nur die Variable nicht durch andere Sammlung neu zugewiesen werden, aber man kann immer noch das Feld in der Sammlung neu zuweisen –

+0

Können Sie mir sagen, wie Sie diese Änderung verhindern können? –

+0

Verwenden Sie einen unveränderlichen Datentyp anstelle eines änderbaren Datentyps. 'Array' ist veränderbar (auch wenn der Verweis darauf nicht ist). Sie können einfach "IndexedSeq" verwenden, das als generisches Merkmal für Sequenzen mit konstantem Direktzugriff dient. Die offizielle Dokumentation hat ein sehr interessantes Kapitel über Sammlungen und ihre Eigenschaften: http://docs.scala-lang.org/overviews/collections/overview.html – stefanobaghino

Antwort

0

Es gibt einen Unterschied zwischen einem wandelbaren erhalten/unveränderliche Variable (zB var x und val x) und eine veränderbare/unveränderbare Sammlung. Die Deklaration von eins (die Variable) beeinflusst nicht die andere (die Sammlung).

Die Scala Array ist von Java geerbt und daher änderbar. Es gibt viele schöne unveränderliche Sammlungen. Array ist nicht einer von ihnen.

+0

Die Tatsache, dass dies eine Matrix ist, lässt mich glauben, dass es wahrscheinlich ist viel zufälliger Zugang sein. Daher wäre die beste Option aus den integrierten unveränderlichen Sammlungen Vector. Betrachtet man jedoch den Code für Vector, sieht es nicht so aus, als sei es auf Scala 2.12.2 spezialisiert. Das bedeutet, dass alle Ints Werte enthalten werden, nicht die 4-Byte-Primitive. Ich würde vorschlagen, ein wenig mehr Code zu schreiben, so dass Sie einen unveränderlichen Wrapper um Array [Array [Int]] mit einer geeigneten Methode erstellen. Wenn Sie eine vollständige Antwort zu diesem Ansatz wünschen, lassen Sie es mich wissen. –

1

Statt Array zu verwenden, vielleicht könnten Sie Liste verwenden stattdessen und es ist unveränderlich:

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

Ich benutze ListBuffer. Können Sie mir sagen, wie kann ich 'scala.collection.mutable.ListBuffer [scala.collection.mutable.ListBuffer [Int]]' zu 'List [List [Int]]' '? –

+0

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

+0

Sie wollen wirklich keine Listen für Matrizen. Sie werden wahrscheinlich zufälliger Zugang sein, so dass dies viel Overhead haben wird. –