• Natively supported Design Patterns.
  • All blocks are treated as expression. Last expression is the return value from the block.

SBT

  • Build tool.
  • It also enables maven repository dependencies to be used in project.

Data types and variables

var age: Int = 12
 
var age = 12
// it inteferences

Lazy initialisation

lazy var age: Int = 12

Scala object

Strings

String interpolation

val name = "hemant"
val age = 12
println("Name: " + name + " Age : " + age)
println(s"Name: $name Age: $age")

Using f

println(f"Name: $name%s Age: $age%d")

Raw string interpolation

println(raw"Hello \n world")
// "Hello \n world"

Conditionals

if-else statement

if (true) {
    //
} else {
    //
}

if-else expression

println(if (true) 5 else 7)

while

while(cond) {
    //
}

do-while

do {
    //
} while(cond)

for statement

for(i <- 1 to 5) {
    println(i)
}

<- is called generator. 1 to 5 creates a range. to is a method on Int 1. It can be rewritten as 1.to(5).

There is until also.

println(1 until 5)
for (i <- 1 to 5; j <- 1 to 3) {
    println(s"i : $i, j : $j")
}

This is a nested loop which gives result as

i : 1, j : 1
i : 1, j : 2
i : 1, j : 3
i : 2, j : 1
i : 2, j : 2
i : 2, j : 3
i : 3, j : 1
i : 3, j : 2
i : 3, j : 3
i : 4, j : 1
i : 4, j : 2
i : 4, j : 3
i : 5, j : 1
i : 5, j : 2
i : 5, j : 3
for (i <- 1 to 10; if i % 2 == 0) {
    println(s"Even number : $i")
}

This shows filtering using for loop by using if conditional.

for expression

for {i <- 1 to 5} yield {
    i * i;
}

match expression

val i = 4;
 
var result = i match {
    case 2 => println(2)
    case 4 => println(4)
    case _ => println("default")
}
var i = 15;
 
var result = i match {
    case 1 | 15 => "matched"
    case _ => "default"
}

Methods

def add(x: Int, y: Int): Int = {
    return x + y;
}
 
def add(x: Int, y: Int): Int = x + y;
 
def add(x: Int, y: Int): Int = {
    x + y;
}

Function

Anonymous function

var add = (x: Int, y: Int) => x + y;

High Order function

A high order function is a function which can take function as an argument or return a function.

def filter(x: List[Int], predicate: (Int) => Boolean) = for {i <- x; if(predicate(i))} yield i;

Partial functions

def add(x: Int, y: Int): Int = x + y;
 
def addTwo = add(2, _: Int)
 
addTwo(2)
 
// 4

Array

var arr = new Array[Int](5)
 
var arr = Array(1, 2, 3, 4)

List

It is different from Array as it is immutable. It uses linked list instead of flat array.

 
var items: List[Int] = List(1, 2, 3, 4)
 
println(items(0)); // not efficient. Why?
 
println(5 :: items) // prepends 1 to list. :: is Cons operator on List. It constructs a new list.
 
println(Nil) // Nil is an empty list. List(). Don't know why 😂
 
println(items.head) // gives the first element
 
println(items.tail) // gives the rest elements other than first element
 
println(items.isEmpty)
 
println(items.reverse) // gives a new list with reversed elements
 
 
var sum = 0;
 
items.foreach(sum += _) // populates sum as addition of all elements. Don't know how it works?

Set

 
var ids: Set[Int] = Set(1, 2, 3)
var ids2: Set[Int] = Set(3, 4, 5)
 
println(ids + 5) // creates a new set with new value
println(ids & ids2) // returns intersection

Map

 
var person: Map[String, String] = Map("name" -> "Nitin", "age" -> "21")
 
println(person("name")) // gives name
 
 
println(person.updated("name", "hemant")) // gives a new map with updated value
 

Tuple

  • Used to store heterogenous data types.
  • Maximum can old upto 22 elements.
  • There is no Tuple class to create or initialise a tuple. () is used to create a tuple.
  • We can access element using properties _<position>.
    • For example, tuple._1 gives first element.
  • 1 -> 3 also gives a tuple (1, 2). -> is a binary operator.
var stats = (1, 2)
 
var stats = Tuple2(1, 2)
 
var stats = Tuple3(1, 2, 3)
 
// .....
var stats = Tuple22(1, 2, ..., 22)
 
 
println(stats._1) // first element

Options

  • An option can have two values Some and None. These are usually used by methods such as find.
  • An option has method get to get the value. getOrElse to provide default value if value doesn’t exist.
 
var opt: Option[Int] = Some(22)
 
println(opt.isEmpty) // false
 
println(opt.get) // gets 22
 
opt = None
 
println(opt.isEmpty) // true
println(opt.get) // throw exception
 
println(opt.getOrElse(2)) // gets 2

map, filter, reduce, fold and scan

numbers.map(_ * 2) // doubles each element
// Or
 
numbers.map(x => x * 2) // doubles each element
  • fold and reduce are same expect fold let’s us pass initial value for the accumulator.
  • scan is same as fold but it also gives intermediate results as well.
var items = List(1, 2, 3)
 
items.scanLeft(0)(_ + _) // it should give List(0, 1, 3, 6)
 
items.scanRight(0)(_ + _) // List(6, 5, 3, 0)

Classes

class Person(var name: String, var age: Int);
 
var person: Person = new Person("Nitin", 12);
 
println(person.name) // gives name
println(person.age) // gives age
 
person.name = "M" // totally works fine
person.age = 22 // totally works fine
 
// ---------------------------------
 
class Person(val name: String, val age: Int);
 
person.name = "M" // can't change
person.age = 22 //  can't change
 
// ---------------------------------
 
class Person(name: String, age: Int);
 
println(person.name) // can't access
println(person.age) // can't access
 
// ---------------------------------
 
class Person(private var name: String, var age: Int);
 
person.name // can't access outside of class.

Thumb rule

TypeGetter?Setter?
varyesyes
valyesno
defaultnono

Class definition

class Person(private var name: String) {
    def getName(): String = {return name}
}
 
var person: Person = new Person("M")
println(person.getName)

Preconditions

  • require is a predefined function to verify if input parameters meet some criteria.
class A(val x: Int) {
    require(x > 9, "message")
}

Auxiliary Constructors

  • We can provide multiple constructors differed in their signature.
  • Each of the auxiliary constructor much call any of the previously defined constructor.

Trait

  • Similar to interface in java.
  • Contains implemented and abstract method.
  • There should be at least one abstract method.

Misc

  • Call by name parameter method.

References

  1. What is {} in foreach ?
  2. Coursera Free Course
  3. https://www.scala-exercises.org/scala_tutorial/terms_and_types
  4. scala test framework
  5. Rock the JVM