This ppt describes basics of scala upto collections covering both object oriented and functional programming concepts of the language.
References:Scala cookbook
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Intro to Scala
1. • Scala is the integration of both object oriented and functional programming concepts.
• Scala runs on JVM
• Scala is statically typed language
• Scala is interop with Java
• “Scala is an acronym for scalable language”
• It grows according to user needs
No boilerplate code! (semicolons, return, getter/setter,
…) Fewer lines of code mean not only less typing, but
also less effort at reading and understanding programs
and fewer possibilities of defects
Scala compiles to Byte Code in the JVM. Scala
programs compile to JVM bytecodes.Their run-time
performance is usually on par with Java programs.
You can write a .class being java or scala code.
Interoperability with Java, So you can easily use the
Java Ecosystem
WHY SCALA? WHAT IS SCALA?
2. HOW TO DEFINE THINGS IN SCALA
IMPLICIT DECLARATION EXPLICIT DECLARATION
Here the data type of the variable will not
be specified. As such compiler assigns
datatype to the variable based up on its
value.
Here the data type of the variable will be
specified
Ex and
syntax:
Ex and
syntax:
DEFINING VARIABLES
• Variables can be directly initialized. Scala compiler figures out the type of the variable.
• var k=1 takes int as the default data type.
• var k=“Hello world” takes string as the default type.
• This is called variable type inference
• Variables can be implicitly or explicitly declared
3. DIFFERENCES BETWEEN VAR AND VAL
VAR VAL
Once we define the variable with var the
variable is mutable(it can be changed)
Once we define the variable with val the
variable is immutable(just like final
variable in java)
It is used mainly in looping structures to
increment an index etc
So for any increment and decrement
operations val is not suitable
Ex:
Note:
There are no increment(++) and decrement(--) operators in Scala instead use += and -= with var type.
4. LET’S KNOW ABOUT CONTROL STRUCTURES
Basic syntax for the for and foreach loop
Note:
Each for loop that iterates over a collection will be converted into a foreach method call on collection.
For loop with a guard is translated to a sequence of a withFilter method call on collection.
For loop with yield expression is translated to a map method call on collection.
For loop Foreach loop
5. NO BREAK AND CONTINUE?
• Unlike most of the programming languages scala doesn’t support break and continue statements.
• But the functionality of break and continue can be brought up through scala.util.control.Breaks
• There are methods break and breakable which are used to implement the functionality
Let us understand how to break out of loop
import scala.util.Breaks._
object Breaks extends App{
breakable{
for(i<-1 to 10){
println(i)
if(i>4) break
}
}
}
An exception is thrown after break “keyword” is reached which will be caught by
breakable And the flow of control continues that is after breakable block.
6. Implementing continue functionality
• Just like break statement continue is implemented using break and breakable methods.
Syntax for break Syntax for continue
breakable{
for(x <- xs){
if(cond)
break
}
}
for(x<-xs){
breakable{
if(cond)
break
}
}
7. IMPLEMENTING SWITCH IN SCALA
• We can use a match expression like a switch statement in scala.
• We need to specify a default case or else compiler throws a match
error if the case for it is not written.
Syntax:
i match{
case 1=> println(“one”)
case 2=>println(“two”)
case _=>println(“default case”)
}
• Apart from this we can also assign the result of match expression to a
variable.
Example:
val evenorodd=number match{
case 1|3|5|7|9=> “odd”
case 2|4|6|8|10=> “even”
}
Matching multiple conditions
with one case statement
8. Using PATTERN MATCHING in match expressions
Constant patterns: It can match only itself
Ex: case 0=>”zero”
case 1=>”one”
Variable patterns: Variable pattern matches any object just like _ wildcard character. For example,
case _=>”anything”
But with variable pattern it can be written as
case foo=>”anything”
Constructor patterns: It lets you match a constructor in a case statement.
Suppose there is a case class like case class Person(name:String)
Then the case statement will be
case Person(“Scala”)=>”given name is Scala”
Sequence patterns: We can match against sequences like List,Array,Vector etc._ specifies for one element in sequence.
_* specifies zero or more elements
Ex: case List(0,_,_) => ”a three element list with 0 as first element”
case Vector(1,_*)=>”vector beginning with 1 having number of elements”
Tuple patterns: Ex: case (a,b,c)=>”tuple with values $a, $b , $c”
Type patterns: The type of the variable will be specified in case statement.
Ex: case str:String=>”you gave me a string of value $str”
9. Matching one or more exceptions with try/catch
• The scala try/catch/finally syntax is similar to Java,but it uses the match expression approach in the catch block.
• Multiple exceptions can be caught by writing multiple case statements.
Note:
while writing multiple case statements in catch block ,first specify the subclass exception that is to be caught and
later a super class exception statement.
10. Scala as object oriented programming language
• Although scala and java share many similarities, the declaration of classes, class constructors and the control of field visibility
are the biggest differences between two languages.
Syntax and example for class:
class Person(var firstname:String){
println(“Constructor begins”)
Val course=“programming”
def printcourse{
println(course)
}
printcourse
println(“end of constructor”)
}
object Person extends App{
val p=new Person(“scala”)
}
Primary constructor
Output:
Constructor begins
Programming
End of constructor
11. CASE CLASSES
• Scala case classes are just regular classes which are immutable by default and decomposable through pattern matching.
• It uses equal method to compare instance structurally.
• Case classes are extensively used in pattern matching.
Basic case class syntax
Error generated while trying to change the variable.This
can be avoided by specifying variable as var(default it is
val)
Note:
case classes generate equals and hashCode methods so that two objects can be compared.
12. OBJECTS
• The word object has dual meaning in scala .As with Java ,we use it to refer to an instance of a class,but in scala,it is also
keyword.
• In general an object is regarded as instance of class,but in scala an application can also be launched by using object.
Launching an application by using object can be done in two ways
1.Extending trait app
2.Manually implementing main method in an object similar to java.
1.Extending app trait
Syntax:
object hello extends App{
println(“hello”)
}
2.Implementing main method
Syntax:
object hello{
def main(args:Array[String]){
}
}
13. COMPANION OBJECTS
• Unlike java or any other programming languages,scala does not support static keyword.
• We can define non static members in class and among them the members that need to be static can be defined in an object
whose name is similar to that of class name. Such object is known as companion object.
Syntax and example:
NOTE:
Both class and companion object can access each other’s
private members
->No need of using new keyword to instantiate an object when we
override apply method in companion object.
Syntax:
object Person{
def apply(name:String):Person={
var p=new Person
p
}
}
14. TRAITS
• In general, Scala traits are just like java’s interfaces.
• Just as Java classes can implement multiple interfaces, Scala can extend multiple traits.
• Unless class implementing a trait is abstract it must implement all of the trait methods.
• If a class extends only one trait, use the extends keyword.
• If a class extends multiple traits, use extends for the first trait and with to extend the other traits.
Traits
15. SCALA AS A FUNCTIONAL PROGRAMMING LANGUAGE
• Scala is both object oriented and functional programming language.
• Functional programming techniques include the ability to define a function and pass them around like instances.
• As Scala supports functional programming features, it encourages an expression oriented programming(EOP) model.It is just
that every expression yields a value
Ex: val k= if (a>b) a else b
ANONYMOUS FUNCTIONS:
It is also known as function literal, so we can pass it into a method that takes function
or assign it to a variable.
Syntax and example:
Val x=List.range(1,10)
Val even=x.filter((i:Int)=>i%2==0))//this yields new list of even numbers
(i:Int)=>i%2==0 is anonymous function here.
Or
Val evens=x.filter(_%2==0)
16. HIGHER ORDER FUNCTIONS
• Functional languages treat functions as first-class values.
• This means that, like any other value, a function can be passed as a parameter and returned as a result.
• This provides a flexible way to compose programs.
• Functions that take other functions as parameters or that return functions as results are called higher order functions.
Consider this example where function
is passed as a parameter
syntax and example
def square(i :Int):Int=i*i
def cube(i:Int):Int=i*i*i
def sumofsquares(f:Int=>Int,x:Int,y:Int)=f(x)+f(y)
val k=sumofsquares(square,10,20)
Function returning a function example:
def urlBuilder(ssl: Boolean, domainName: String): (String, String) =>
String = {
val schema = if (ssl) "https://" else http://
(endpoint: String, query: String) => s"$schema$domainName/$endpoint?
$query" }
val domainName = www.example.com
def getURL = urlBuilder(ssl=true, domainName)
val endpoint = "users"
val query = "id=1“
val url = getURL(endpoint, query) // https://www.example.com/users?id=1
: String
17. CLOSURES
• Closure is a function whose return value depends upon two or more variables defined outside the function .
Example:
package scope{
class Foo{
def exec(f:String=>Unit,name:String){
f(name)
}}}
object example extends App{
var hello=“Hello”
def sayHello(name:String){
println(“$hello,$name”)
}
val foo=new otherscope.Foo
foo.exec(sayHello,”Scala”)
hello=“Hola”
foo.exec(sayHello,”Programming”)
}
}
Note:
Scala’s closure functionality lets it access the hello
variable present in same scope for sayHello function.
18. PARTIALLY APPLIED FUNCTIONS
• Scala like many other programming languages allow partial functionality which is while calling a function
we can send only few arguments and leaving other variables to be passed later.
Example
object scala extends App{
val sum=(a:Int,b:Int,c:int)=>a+b+c
def main(args:Array[String]){
val f=sum(1,2,_:Int)
println(f(3))
}
}
Automatically passes the value ‘3’ as the third argument and returns the sum of three
numbers
19. Creating a function that returns a function
Suppose there is a function
def say(prefix:String)=(s:String)=>{
prefix+” “+s}
val sayHello=say(“hello)
println(sayHello(“Scala”))
output:
Hello scala
This function can be broken into 2 sub components
1.def say(prefix:String). and
2.(s:String)=>{prefix+” “+s} ->this is an anonymous function.
Here sayHello function is now equivalent to anonymous function,
with prefix set to hello.So we now pass a string to sayHello as
anonymous function takes String as a parameter.
Note:
Functions can also be written by using PATTERN MATCHING.
ex: def what(any:Any)=any match{
case i:Int=>”you gave an integer”
case i:String=>”you gave a string”
case _=>”Unable to decode it”
}
20. COLLECTIONS IN SCALA
• Scala’s collections are rich, deep and differ significantly from Java’s collections.
• Scala collections systematically distinguish between mutable and immutable collections. A mutable collection
can be updated or extended in place.
• This means you can change, add, or remove elements of a collection as a side effect.
• Immutable collections, by contrast, never change. You have still operations that simulate additions, removals,
or updates, but those operations will in each case return a new collection and leave the old collection unchanged.
THE COLLECTION HIERARCHY
At high level, scala’s collection classes begin with the Traversable
and Iterable traits and extend into three main categories of sequence
set and maps.
21. MUTABLE AND IMMUTABLE COLLECTIONS
Immutable
As we can see vector is immutable here , when we use variable(var) to a immutable collection you can add elements into it
but causes a surprising behaviour
Suppose there is a vector => var sisters=Vector(“Melinda”)
Sisters=sisters:+”Melissa”
Here we are mutating an immutable collection,each time we use :+ method as the sisters variable is mutable,it is actually
being assigned to new collection during each step.
22. Immutable collections
Creating collections in scala.
• For a collection which can be both immutable and mutable like
hash map the default implementation will be immutable.Mutable
hash map can be created by using import statement to bring it into
Scope or specify full path while creating instance.
Var states=Map(“Al”->”Alabama”,”Ak”,->”Alaska”)
var states=collection.mutable.Map(“Al”=>”Alabama”)
or
Import scala.collection.mutable.Map
var states=map(“AL”=>”Alabama”)
24. SOME COMMON COLLECTIONS USED
LIST:
Creating the lists:
There are many ways to create and populate a list.
Val list=1::2::3::4::Nil
Val list=List(1,2,3)
Val list=List(1,2.0,33D,4000L)//not specifying a particular type for list.
Val list=List[Number](1,2.0)//specifying the particular type
Val list=List.fill(3)(“foo”)//list=List(foo,foo,foo)
Val list=List.tabulate(5)(n=>n*n)//populating the list -list=List(0,1,4,9,16)
In general lists are immutable so to implement mutable functionality we can use ListBuffer and
later convert it into a list.
Example:
var f=new ListBuffer[String]()//Creating an empty list buffer
f+=“apple”
f+=“banana”
f-=“apple”
val flist=f.toList
25. ARRAYS
Creating and populating an array:
Val x=Array(1,2.0,33D)//It takes default array type as double
Val x=Array[Int](1,2,3,4)
Var x=new Array[String](3)//creating an array with an initial size
Multidimensional arrays:
Val rows=2
Val cols=1
Val a=Array.ofDim[String](rows,cols)
A(0)(0)=“a”
A(1)(0)=“b”
Just like a list array is immutable to its size so here we use ArrayBuffer to change
the size of an array.
Example:
Var char=collection.mutable.ArrayBuffer[String]()
Char+=“Ben”
Char+=“ken”
Later arraybuffer can be converted into array bu using toArrray method.
Note:
An array can easily be sorted by
using quicksort algo present in
scala.util.Sorting.quicksort
Syntax:
Val a=Array(“a”,”b”)
quicksort(a)
26. MAPS
Creating immutable map: //no need for import statement
Val states=Map(“Al”->”Alabama”,”Ak”,->”Alaska”)
For mutable map
var states=collection.mutable.states=Map(“Al”->”Alabama”,”Ak”,->”Alaska”)
There are many maps in scala. Suitable to a particular situation one of them can be chosen.
1.To get a map that sorts elements by their keys use sorted map.
Val grades=SortedMap(“Kim”->90,”Al”->91)//grades=(“Al”->91,”Kim”->90)
2.To get a map that remembers the insertion order of its elements , use a LinkedHashMap or ListMap. Scala has only mutable
LinkedHashMap and its returns its elements in the order they are inserted.
Val states=collections.mutable.LinkedHashMap(“Al”->”Alabama”)
States+=(“Ak”->”Alaska”)
3.List map gives the reverse order to the order in which they are inserted. Just like lists where each insert was at head of the
map(List).
Var states=Collections.mutable.Listmap(“Al”->”Alabama”)
States+=(“Ak”->”Alaska”)
//States=(“Ak”->”Alaska”,”Al”->”Alabama”)
Note: To avoid exception(NoSuchElementException) while accessing a value whose key is not present in map.Create
Map in this way.
Val states=Map(“Al”->”Alabama”).withDefaultValue(“NotFound”).
27. QUEUES
The queue data structure can be used in scala applications by importing scala.collection.mutable.Queue
Queue is a first-in-first-out data structure.
Creating a queue:
Val q=Queue[Int](1,2,3)//A queue can be created like any other collection.
Q+=(4)
q.enqueuer(5)//can also use enqueue.
Val n=q.dequeue//takes element from head of queue- 1
q.dequeueAll(_.length==1)//removes all elements from queue whose length is one
Similarly dequeueFirst can be used to check on first element in queue and then remove it.
28. STACK
• A stack is a Last-In-First-Out data structure .
• In most programming languages we perform operations on stack by using push and pop methods. Even in scala these
methods are present.
Scala has both mutable and immutable versions of stack.
Mutable stack:
Val ints=Stack[Int]()
ints.push(1)//stack=1
ints.push(2)//stack=1,2
val n =ints.pop//n=2
val k=ints.top//k=1
29. SOME IMPORTANT METHODS PERFORMED ON COLLECTIONS
FILTER
MAP
FLATTEN
Filter is used to filter the items in a collection to create a new collection that contains only the elements that match
the filtering criteria.
Example and syntax:
Val x=Map(1->”a”,2->”b”)
Val y=x.filter((t) => t._1 > 1)//return map(2->b)
Map is used for executing same code on very element in a collection and returns new collection with updated
elements.
Example and Syntax:
Val x=List(“apple”,”banana”)
Val y=x.map(c=>c.toUpperCase())//y=(APPLE,BANANA)
Flatten method is used to convert list of lists into a single list.
Example and syntax:
Val list1=List(1,2,3)
Val list2=List(4,5,6)
Val list3=List(list1,list2)
Val list4=list3.flatten//list4=(1,2,3,4,5,6)