Scala Class that containing List - scala

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.

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.

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.
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.

Related

Why this class need to be abstract in scala?

In java and c#,I can write this:
class Tree {
Tree left;
Tree right;
}
but in scala:
class Tree{
val left:Tree
val right:Tree
}
I need to add abstract for class,or write:
val left:Tree=new Tree()
I can write this:
trait Tree{
val left:Tree
val right:Tree
}
but why if I use class,I "have to"and abstract?I don't think it's a good design
Thanks!
The reason you can write
class Tree {
Tree left;
Tree right;
}
in Java and C# is because the fields are initialized to null by default (or to 0, etc. depending on the type). Scala's designers decided this is a bad idea and you need to initialize them. So the approximate Scala equivalent is
class Tree {
// note, not val
var left: Tree = null
var right: Tree = null
}
which is legal (but probably not something you actually want to use).
but why if I use class,I "have to"and abstract?
You have to mark your class with the abstract keyword because your class is abstract. It cannot possibly be instantiated.
I don't think it's a good design
Good design is subjective. The designers of Scala thought that being explicit in this case, rather than making the class automatically abstract was good design. I would guess that the majority of the Scala community agrees with them.
You disagree, and that is perfectly okay.
It happened because scala sometimes considers val and def as method like declarations. Let me elaborate, please, for instance, we have the next Scala example:
class Example {
val a: String = "example"
}
val example = new Example()
println(example.a)
You may see that a declared as a field. Unlike Java, we can change this declaration easily to def and everything remains compiling:
class Example {
def a: String = "example"
}
val example = new Example()
println(example.a)
In the case of Java (not sure about C# I've never worked with it), if you would like to access the field over getter method, you will need to change all invocation places from field to method access.
Now, you can consider val as let's say sort of eager cached def version - if so then declaring val without actually value assignment implicitly considered by compiler as declaring method without implementation and that's why compiler says Tree is an abstract class - because left and right has no values, hence they are abstract. In order to make it non-abstract, you need to assign a value to fields or use var if you would like to proceed with mutable structure, e.g.:
class Example {
val a: String = "example"
}
val example = new Example()
println(example.a)
Scatie: https://scastie.scala-lang.org/bQIcVNk9SN6qJhbL32SMUQ

Understanding companion object in scala

While learning Scala, I came across interesting concept of companion object. Companion object can used to define static methods in Scala. Need few clarifications in the below Spark Scala code in regard of companion object.
class BballStatCounter extends Serializable {
val stats: StatCounter = new StatCounter()
var missing: Long = 0
def add(x: Double): BballStatCounter = {
if (x.isNaN) {
missing += 1
} else {
stats.merge(x)
}
this
}
}
object BballStatCounter extends Serializable {
def apply(x: Double) = new BballStatCounter().add(x)
}
Above code is invoked using val stat3 = stats1.map(b=>BballStatCounter(b)).
What is nature of variables stats and missing declared in the
class? Is it similar to class attributes of Python?
What is the significance of apply method in here?
Here stats and missing are class attributes and each instance of BballStatCounter will have their own copy of them just like in Python.
In Scala the method apply serves a special purpose, if any object has a method apply and if that object is used as function calling notation like Obj() then the compiler replaces that with its apply method calling, like Obj.apply() .
The apply method is generally used as a constructor in a Class Companion object.
All the collection Classes in Scala has a Companion Object with apply method, thus you are able to create a list like : List(1,2,3,4)
Thus in your above code BballStatCounter(b) will get compiled to BballStatCounter.apply(b)
stats and missing are members of the class BcStatCounter. stats is a val so it cannot be changed once it has been defined. missing is a var so it is more like a traditional variable and can be updated, as it is in the add method. Every instance of BcStatCounter will have these members. (Unlike Python, you can't add or remove members from a Scala object)
The apply method is a shortcut that makes objects look like functions. If you have an object x with an apply method, you write x(...) and the compiler will automatically convert this to x.apply(...). In this case it means that you can call BballStatCounter(1.0) and this will call the apply method on the BballStatCounter object.
Neither of these questions is really about companion objects, this is just the normal Scala class framework.
Please note the remarks in the comments about asking multiple questions.

How does the object in class pattern work, as used in the Lift Framework?

I'm new to scala and can't get my head around how the Lift guys implemented the Record API. However, the question is less about this API but more about Scala in general. I'm interested in how the object in class pattern works, used in Lift.
class MainDoc private() extends MongoRecord[MainDoc] with ObjectIdPk[MainDoc] {
def meta = MainDoc
object name extends StringField(this, 12)
object cnt extends IntField(this)
}
object MainDoc extends MainDoc with MongoMetaRecord[MainDoc]
In the upper snippet you can see how a record is defined in Lift. The interesting part is that the fields are defined as objects. The API allows you to create Instances like this:
val md1 = MainDoc.createRecord
.name("md1")
.cnt(5)
.save
This is probably done by using the apply method? But at the same time you are able to get the values by doing something like this:
val name = md1.name
How does this all work? Are the objects not that static when in scope of an class. Or are they just constructor classes for some internal representation? How is it possible to iterate over all fields, do you use Reflection?
Thanks,
Otto
Otto,
You are more of less on the right track. You actually don't need to define your fields as objects, you could have written your example as
class MainDoc private() extends MongoRecord[MainDoc] with ObjectIdPk[MainDoc] {
def meta = MainDoc
val name = new StringField(this, 12)
val cnt= new IntField(this)
}
object MainDoc extends MainDoc with MongoMetaRecord[MainDoc]
The net.liftweb.record.Field trait does contain an apply method that is the equivalent to set. That's why you can assign the fields by name after instantiating the object.
The field reference you mentioned:
val name = md1.name
Would type name as a StringField. If what you were thinking was
val name: String = md1.name
that would fail to compile (unless there was an implicit in scope to convert Field[T] => T). The proper way retrieve the String value of the field would be
val name = md1.name.get
Record does use reflection to gather the fields. When you define an object within a class, the compiler will create a field to hold the object instance. From the standpoint of reflection, the object appears very similar to the alternate way to define a field that I mentioned before. Each of the definitions probably creates a subclass of the field type, but that's no different than
val name = new StringField(this, 12) {
override def label: NodeSeq = <span>My String Field</span>
}
You're right about it being the apply method. Record's Field base class defines a few apply methods.
def apply(in: Box[MyType]): OwnerType
def apply(in: MyType): OwnerType
By returning the OwnerType, you can chain invocations together.
Regarding the use of object to define fields, that confused me at first, too. The object identifier defines an object within a particular scope. Even though it's convenient to think of object as a shortcut for the singleton pattern, it's more flexible than that. According to the Scala Language Spec (section 5.4):
It is roughly equivalent to the following definition of a lazy value:
lazy val m = new sc with mt1 with ... with mtn { this: m.type => stats }
<snip/>
The expansion given above is not accurate for top-level objects. It cannot be because variable and method definition cannot appear on the top-level outside of a
package object (§9.3). Instead, top-level objects are translated to static fields.
Regarding iterating over all the fields, Record objects define a allFields method which returns a List[net.liftweb.record.Field[_, MyType]].

How to define a parameterless constructor in Scala

This question is so stupid... Anyway, i just can't find the right information, because every Scala-constructor example class i see works with at least one parameter.
I want to have this class translated from Java to Scala:
public class SubscriptionConverter extends Converter {
public SubscriptionConverter() {
Context ctx = new InitialContext();
UserEJB userEJB = (UserEJB) ctx.lookup("java:global/teachernews/UserEJB");
}
(...)
}
So i only have a parameterless constructor. I messed around in Scala with this(), but i couldn't get a similar example like the one above working.
How do i do i write that in Scala?
Any statements declared at the class level are executed as part of the default constructor. So you just need to do something like this:
class SubscriptionConverter extends Converter {
val ctx = new InitialContext
val userEJB = ctx.lookup("java:global/teachernews/UserEJB")
(...)
}
#dbyrne has covered the most important parts, but I'll add a few side details.
If a class has no parameters, and it's immutable, consider declare it as an object instead.
The constructor defined by statements at the class level and by parameter lists after the class name is known as the primary constructor. * Auxiliary constructors* are defined by def this() = .... Unlike Java, each auxiliary constructor must delegate to the primary constructor.
When you declare a primary constructor with zero parameter lists, the compiler will automatically add a single, empty parameter list. If you define a constructor with one implicit parameter list, the compiler will add an empty parameter list before this.

Difference between object and class in Scala

I'm just going over some Scala tutorials on the Internet and have noticed in some examples an object is declared at the start of the example.
What is the difference between class and object in Scala?
tl;dr
class C defines a class, just as in Java or C++.
object O creates a singleton object O as instance of some anonymous class; it can be used to hold static members that are not associated with instances of some class.
object O extends T makes the object O an instance of trait T; you can then pass O anywhere, a T is expected.
if there is a class C, then object C is the companion object of class C; note that the companion object is not automatically an instance of C.
Also see Scala documentation for object and class.
object as host of static members
Most often, you need an object to hold methods and values/variables that shall be available without having to first instantiate an instance of some class.
This use is closely related to static members in Java.
object A {
def twice(i: Int): Int = 2*i
}
You can then call above method using A.twice(2).
If twice were a member of some class A, then you would need to make an instance first:
class A() {
def twice(i: Int): Int = 2 * i
}
val a = new A()
a.twice(2)
You can see how redundant this is, as twice does not require any instance-specific data.
object as a special named instance
You can also use the object itself as some special instance of a class or trait.
When you do this, your object needs to extend some trait in order to become an instance of a subclass of it.
Consider the following code:
object A extends B with C {
...
}
This declaration first declares an anonymous (inaccessible) class that extends both B and C, and instantiates a single instance of this class named A.
This means A can be passed to functions expecting objects of type B or C, or B with C.
Additional Features of object
There also exist some special features of objects in Scala.
I recommend to read the official documentation.
def apply(...) enables the usual method name-less syntax of A(...)
def unapply(...) allows to create custom pattern matching extractors
if accompanying a class of the same name, the object assumes a special role when resolving implicit parameters
A class is a definition, a description. It defines a type in terms of methods and composition of other types.
An object is a singleton -- an instance of a class which is guaranteed to be unique. For every object in the code, an anonymous class is created, which inherits from whatever classes you declared object to implement. This class cannot be seen from Scala source code -- though you can get at it through reflection.
There is a relationship between object and class. An object is said to be the companion-object of a class if they share the same name. When this happens, each has access to methods of private visibility in the other. These methods are not automatically imported, though. You either have to import them explicitly, or prefix them with the class/object name.
For example:
class X {
// class X can see private members of object X
// Prefix to call
def m(x: Int) = X.f(x)
// Import and use
import X._
def n(x: Int) = f(x)
private def o = 2
}
object X {
private def f(x: Int) = x * x
// object X can see private members of class X
def g(x: X) = {
import x._
x.o * o // fully specified and imported
}
}
An object has exactly one instance (you can not call new MyObject). You can have multiple instances of a class.
Object serves the same (and some additional) purposes as the static methods and fields in Java.
As has been explained by many, object defines a singleton instance. The one thing in the answers here that I believe is left out is that object serves several purposes.
It can be the companion object to a class/trait, containing what might be considered static methods or convenience methods.
It can act much like a module, containing related/subsidiary types and definitions, etc.
It can implement an interface by extending a class or one or more traits.
It can represent a case of a sealed trait that contains no data. In this respect, it's often considered more correct than a case class with no parameters. The special case of a sealed trait with only case object implementors is more or less the Scala version of an enum.
It can act as evidence for implicit-driven logic.
It introduces a singleton type.
It's a very powerful and general construct. What can be very confusing to Scala beginners is that the same construct can have vastly different uses. And an object can serve many of these different uses all at once, which can be even more confusing.
Defining an object in Scala is like defining a class in Java that has only static methods. However, in Scala an object can extend another superclass, implement interfaces, and be passed around as though it were an instance of a class. (So it's like the static methods on a class but better).
The formal difference -
you can not provide constructor parameters for Objects
Object is not a type - you may not create an instance with new operator. But it can have fields, methods, extend a superclass and mix in traits.
The difference in usage:
Scala doesn't have static methods or fields. Instead you should use object. You can use it with or without related class. In 1st case it's called a companion object. You have to:
use the same name for both class and object
put them in the same source file.
To create a program you should use main method in object, not in class.
object Hello {
def main(args: Array[String]) {
println("Hello, World!")
}
}
You also may use it as you use singleton object in java.
  
    
  
In scala, there is no static concept. So scala creates a singleton object to provide entry point for your program execution.
If you don't create singleton object, your code will compile successfully but will not produce any output. Methods declared inside Singleton Object are accessible globally. A singleton object can extend classes and traits.
Scala Singleton Object Example
object Singleton{
def main(args:Array[String]){
SingletonObject.hello() // No need to create object.
}
}
object SingletonObject{
def hello(){
println("Hello, This is Singleton Object")
}
}
Output:
Hello, This is Singleton Object
In scala, when you have a class with same name as singleton object, it is called companion class and the singleton object is called companion object.
The companion class and its companion object both must be defined in the same source file.
Scala Companion Object Example
class ComapanionClass{
def hello(){
println("Hello, this is Companion Class.")
}
}
object CompanoinObject{
def main(args:Array[String]){
new ComapanionClass().hello()
println("And this is Companion Object.")
}
}
Output:
Hello, this is Companion Class.
And this is Companion Object.
In scala, a class can contain:
1. Data member
2. Member method
3. Constructor Block
4. Nested class
5. Super class information etc.
You must initialize all instance variables in the class. There is no default scope. If you don't specify access scope, it is public. There must be an object in which main method is defined. It provides starting point for your program. Here, we have created an example of class.
Scala Sample Example of Class
class Student{
var id:Int = 0; // All fields must be initialized
var name:String = null;
}
object MainObject{
def main(args:Array[String]){
var s = new Student() // Creating an object
println(s.id+" "+s.name);
}
}
I am sorry, I am too late but I hope it will help you.
The object keyword creates a new singleton type, which is like a class that only has a single named instance. If you’re familiar with Java, declaring an object in Scala is a lot like creating a new instance of an anonymous class.
Scala has no equivalent to Java’s static keyword, and an object is often used in Scala where you might use a class with static members in Java.
Object is a class but it already has(is) an instance, so you can not call new ObjectName. On the other hand, Class is just type and it can be an instance by calling new ClassName().
A class is just like any other class in other languages. You define class just like any other language with some syntax difference.
class Person(val name: String)
val me = new Person("My name")
However, object is a class with single object only. This makes it interesting as it can be used to create static members of a class using companion object. This companion object has access to private members of the class definition and it has the same name as the class you're defining.
class Person(var name: String) {
import Person._
def hi(): String = sayHello(name)
}
object Person {
private def sayHello(name: String): String = "Hello " + name
}
val me = new Person("My name")
me.hi()
Also, noteworthy point is that object class is lazily created which is another important point. So, these are not instantiated unless they are needed in our code.
If you're defining connection creation for JDBC, you can create them inside object to avoid duplication just like we do in Java with singleton objects.
Scala class same as Java Class but scala not gives you any entry method in class, like main method in java. The main method associated with object keyword. You can think of the object keyword as creating a singleton object of a class that is defined implicitly.
more information check this article
class and object keyword in scala programming
The object is similar to the static class in Java to some extend, the static characteristic means the static class need not to create an object when putting to the JVM, it can be used by it's class name directly and the same instance(same data state) is shared wherever it is used.
If you are coming from java background the concept of class in scala is kind of similar to Java, but class in scala cant contain static members.
Objects in scala are singleton type you call methods inside it using object name, in scala object is a keyword and in java object is a instance of class