- 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.
- For example,
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
andNone
. These are usually used by methods such asfind
. - 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
andreduce
are same expectfold
let’s us pass initial value for the accumulator.scan
is same asfold
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
Type | Getter? | Setter? |
---|---|---|
var | yes | yes |
val | yes | no |
default | no | no |
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.