2

I have the following class:

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

I have declared class variable as val to prevent further modification in 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)
  }
}

After doing x(1)(1) = 101 the output of the program is

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

But I want to prevent this modification and get the original matrix as

m1 -->
1 2 3
4 5 6
7 8 9
3
  • val only makes the variable cannot be reassigned by other collection but you still can reassign the field in the collection Commented Jul 3, 2017 at 7:08
  • Could you tell me how to prevent this modification? Commented Jul 3, 2017 at 7:21
  • Use an immutable data type instead of a mutable one. Array is mutable (even if the reference to it is not). You can simply use IndexedSeq which serves as a generic trait for sequences with constant random access. The official documentation has a very interesting chapter on collections and their characteristics: docs.scala-lang.org/overviews/collections/overview.html Commented Jul 3, 2017 at 7:52

2 Answers 2

1

Instead of using Array, maybe you could use List instead, and it is immutable :

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
   ^
Sign up to request clarification or add additional context in comments.

3 Comments

I am using ListBuffer. Could you tell me how can I cast scala.collection.mutable.ListBuffer[scala.collection.mutable.ListBuffer[Int]] to List[List[Int]]?
buff.map(_.toList).toList
You really don't want Lists for matrices. They are likely going to be random access so this will have a lot of overhead.
0

There's a difference between a mutable/immutable variable (e.g. var x and val x) and a mutable/immutable collection. Declaring one (the variable) doesn't effect the other (the collection).

The Scala Array is inherited from Java and, as such, is mutable. There are many fine immutable collections. Array isn't one of them.

1 Comment

The fact that this is a matrix leads me to believe that there is likely to be a lot of random access. As such, the best option from the built-in immutable collections would be Vector. However, looking at the code for Vector it doesn't appear that it is specialized as of Scala 2.12.2. That means that all the Ints will be wrapped values, not the 4-byte primitives. I would suggest writing a bit more code so you create an immutable wrapper around Array[Array[Int]] with an appropriate apply method. If you would like a full answer on this approach, let me know.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.