ugur
ugur

Reputation: 410

Scala Class that containing List

I have a very basic and simple Scala question. For example, I have a java class like that

class Dataset{
   private List<Record> records;
   Dataset(){
       records = new ArrayList<Record>()
   }
   public void addItem(Record r){
       records.add(r)


      }
}

When I try to write same class in Scala, I encoutered with some error:

class RecordSet() {

  private var dataset:List[Record]
  def this(){
    dataset = new List[Record]
  }

  def addRecord(rd: Record)={
    dataset :+ rd
  }

}

I cannot declare a List variable like ( private var dataset:List[Record]) and cannot write a default constructor.

Upvotes: 0

Views: 406

Answers (2)

anuj saxena
anuj saxena

Reputation: 279

  1. As dade told the issue in your code is that with this keyword you are actually creating an auxilary constructor which has some limitations like the first line of your auxilary constructor must be another constructor (auxilary/primary). Hence you cannot use such a way to create a class.

    1. Also you can not write such lines in a scala concrete class private var dataset:List[Record] as it is considered as abstract (no definition provided).

Now with the code. Usually in Scala we don't prefer mutability because it introduces side-effects in our functions (which is not the functional way but as scala is not purely functional you can use mutability too).

In Scala way, the code should be something like this:

  class RecordSet(private val dataset:List[Record]) {
    def addRecord(rd: Record): RecordSet ={
      new RecordSet(dataset :+ rd)
    }
  }

Now with the above class there is no mutability. Whenever you are adding on an element to the dataset a new instance of RecordSet is being created. Hence no mutability.

However, if you have to use the same class reference in your application use your a mutable collection for your dataset like below:

  class RecordSet(private val dataset:ListBuffer[Record]) {

    def addRecord(rd: Record): ListBuffer[Record] ={
      dataset += rd
    }
  }

Above code will append the new record in the existing dataset with the same class reference.

Upvotes: 1

dade
dade

Reputation: 3570

Here is how you will replicate the Java code you mentioned in your question:

// defining Record so the code below compiles
case class Record() 

// Here is the Scala implementation
class RecordSet(private var dataset:List[Record]) {
    def addRecord(rd: Record)={
      dataset :+ rd
    }
  }

Some explanation:

In Scala, when you define a class, you have the ability to pass parameter to the class definition. eg: class Foo(num:Int, descr:String) Scala would automatically use the given parameter to create a primary constructor for you. So you can now instantiate the Foo, like so new Foo(1, "One"). This is different in Java where you have to explicitly define parameter accepting constructors.

You have to be aware that the parameter passed do not automatically become instance member of the class. Although if you want, you can tell Scala to make them instance member. There are various ways to do this, one way is to prefix the parameter with either var or val. For example class Foo(val num:Int, val descr:String) or class Foo(var num:Int, var descr:String). The difference is that with val, the instance variable are immutable. With var they are mutable.

Also, by default the instance member Scala will generate would be public. That means they can be accessed directly from an instance of the object. For example:

val foo = new Foo(1, "One")
println(foo.num) // prints 1.

If you want them to be private, you add private keyword to the definition. So that would become:

class Foo(private var num:Int, private var desc:String)

The reason why your code fails to compile is you define a method called this() which is used to create multiple constructors. (and not to create a constructor that initiates a private field which is your intention judging from the Java code you shared). You can google for multiple constructors or auxiliary constructors to learn more about this.

Upvotes: 2

Related Questions