Scala Tutorial
Scala Tutorial
Scala Tutorial
•Visit Scala Website and then Downloads. Find scala-2.12.6.deb (Debian) and copy Link Address.
Scala, short for Scalable Language, is a hybrid functional programming language. It was created by Martin Odersky. Scala
smoothly integrates the features of object-oriented and functional languages. Scala is compiled to run on the Java Virtual
Machine.
Scala is object-oriented:
Scala is a pure object-oriented language in the sense that every value is an object. Types and behavior of objects are
described by classes and traits.
Scala is functional:
Scala is also a functional language in the sense that every function is a value and every value is an object so ultimately every
function is an object.
Scala provides a lightweight syntax for defining anonymous functions, it supports higher-order functions, it allows functions
to be nested, and supports currying.
Running First Scala Program:
We can execute a Scala program in two modes: one is interactive mode and another is script mode.
•Interactive Mode
Open the command prompt and use the following command to open Scala.
$ scala
Welcome to Scala 2.12.6 (Java Hotspot (TM) Server VM, Java 1.8.0_171).
Type the following text to the right of the Scala prompt and press the Enter key −
Welcome to Scala
• Script Mode
Use the following instructions to write a Scala program in script mode. Open Text Editor and add the following code
into it.
object HelloWorld {
def main(args: Array[String]) {
println("Hello, world")
}
}
Use the following command to compile and execute your Scala program.
$ scalac HelloWorld.scala
•Case Sensitivity − Scala is case-sensitive, which means identifier Hello and hello would have different meaning in Scala.
•Class Names − For all class names, the first letter should be in Upper Case. If several words are used to form a name of the
class, each inner word's first letter should be in Upper Case.
Example − class HelloWorld
•Method Names − All method names should start with a Lower Case letter. If multiple words are used to form the name of
the method, then each inner word's first letter should be in Upper Case.
Example − def myMethodName()
•Program File Name − Name of the program file should exactly match the object name. When saving the file you should
save it using the object name (Remember Scala is case-sensitive) and append ‘.scala’ to the end of the name. (If the file
name and the object name do not match your program will not compile).
Example − Assume 'HelloWorld' is the object name. Then the file should be saved as 'HelloWorld.scala'.
•def main(args: Array[String]) − Scala program processing starts from the main() method which is a mandatory part of
every Scala Program.
Scala Identifiers:
All Scala components require names. Names used for objects, classes, variables and methods are called identifiers. A
keyword cannot be used as an identifier and identifiers are case-sensitive. Scala supports four types of identifiers.
Alphanumeric Identifiers:
An alphanumeric identifier starts with a letter or an underscore, which can be followed by further letters, digits, or
underscores. The '$' character is a reserved keyword in Scala and should not be used in identifiers.
Mixed Identifiers:
A mixed identifier consists of an alphanumeric identifier, which is followed by an underscore and an operator identifier.
Variable is a name which is used to refer memory location. You can create mutable and immutable variable in scala.
Mutable Variable:
You can create mutable variable using var keyword. It allows you to change value after declaration of variable.
var data = 100
data = 101 // It works, No error.
In the above code, var is a keyword and data is a variable name. It contains an integer value 100. Scala is a type infers
language so you dont need to specify data type explicitly. You can also mention data type of variable explicitly as used
below.
val data:Int = 100 // Here, we have mentioned Int followed by : (colon)
Immutable Variable:
val data = 100
data = 101 // Error: reassignment to val
The above code throws an error because we have changed content of immutable variable, which is not allowed. So if
you want to change content then it is advisable to use var instead of val.
When you assign an initial value to a variable, the Scala compiler can figure out the type of the variable based on the
value assigned to it. This is called variable type inference. Therefore, you could write these variable declarations like
this −
Syntax
var myVar = 10;
val myVal = "Hello, Scala!";
Here, by default, myVar will be Int type and myVal will become String type variable.
Multiple Assignments:
Scala supports multiple assignments. If a code block or method returns a Tuple (Tuple − Holds collection of Objects of
different types), the Tuple can be assigned to a val variable.
Syntax
val (myVar1: Int, myVar2: String) = Pair(20, “Rahul")
And the type inference gets it right −
Syntax
val (myVar1, myVar2) = Pair(20, “Rahul")
Example:
object Test {
def main(args: Array[String]) {
var myVar :Int = 10;
val myVal :String = "Hello Scala with datatype declaration.";
var myVar1 = 20;
val myVal1 = "Hello Scala new without datatype declaration.";
println(myVar); println(myVal); println(myVar1);
println(myVal1);
}
}
Scala - Data Types:
Scala has all the same data types as Java, with the same memory footprint and precision. Following is the table giving
details about all the data types available in Scala.
Sr.No Data Type & Description
object Test {
def main(args: Array[String]) {
var a = 10;
while( a<=51){
println( "Value of a: " + a );
a=a+10;
}
}
}
Do While Loop Example:
object TestDo {
def main(args: Array[String]) {
var a = 0;
do {
a=a+10;
println( "Value of a: " + a );
}while(a<=51);
}
}
Scala for-loop Example by using to keyword
object Testfor {
def main(args: Array[String]) {
var a = 0;
for( a <- 1 to 10){
println( "Value of a: " + a );
}
}
}
Scala for-loop Example by using until keyword
object Testfor {
def main(args: Array[String]) {
var a = 0;
for( a <- 1 until 10){
println( "Value of a: " + a );
}
}
}
The major difference between until and to is, to includes start and end value given in the range, while until excludes last
value of the range.
Scala for-loop filtering Example
Use for to filter your data. In the below example, we are filtering our data by passing a conditional expression. This program
prints only even values in the given range.
object TestFilter {
def main(args: Array[String]) {
for( a <- 1 to 10 if a%2==0 ){
println(a);
}
}
}
yield keyword returns a result after completing of loop iterations. The for use buffer internally to store iterated result and
after finishing all iterations it yields the final result from that buffer. It does not work like imperative loop.
object TestYield {
def main(args: Array[String]) {
var result = for( a <- 1 to 10) yield a
for(i<-result){
println(i)
}
}
}
object TestLoop {
def main(args: Array[String]) {
var list = List(1,2,3,4,5,6,7,8,9)
for( i <- list){
println(i)
}
}
}
Scala for-each loop Example for Iterating Collection
object TestLoop {
def main(args: Array[String]) {
var list = List(1,2,3,4,5,6,7,8,9)
list.foreach{
println
}
list.foreach(print)
println
list.foreach((element:Int)=>print(element+" "))
}
}
Scala for-loop Example using by keyword
The by keyword is used to skip the iteration. When you code like: by 2 it means, this loop will skip all even iterations of
loop.
object TestLoop {
def main(args: Array[String]) {
for(i<-1 to 10 by 2){
println(i)
}
}
}
Scala Functions
Scala supports functional programming approach. It provides rich set of built-in functions and allows you to create user
defined functions also.
In scala, functions are first class values. You can store function value, pass function as an argument and return function as
a value from other function. You can create function by using def keyword. You must mention return type of parameters
while defining function and return type of a function is optional. If you don't specify return type of a function, default
return type is Unit.
Syntax:
def functionName(parameters : typeofparameters) : returntypeoffunction = {
// statements to be executed
}
In the syntax, = (equal) operator is looking strange but don't worry scala has defined it as:
You can create function with or without = (equal) operator. If you use it, function will return value. If you don't use it, your
function will not return anything and will work like subroutine.
object Test {
def main(args: Array[String]) {
functionExample()
}
def functionExample() {
println(“Welcome to Scala Function")
}
}
Scala Function Example with = Operator:
object Test {
def main(args: Array[String]) {
var result = Testfunction()
println(result)
}
def Testfunction() = {
var a = 10
a
}
}
When using parameterized function you must mention type of parameters explicitly otherwise compiler throws an error
and your code fails to compile.
object Test {
def main(args: Array[String]) = {
Testfunction(10,20)
}
def Testfunction(a:Int, b:Int) = {
var c = a+b
println(c)
}
}
In the program given below, we are multiplying two numbers by using recursive function.
In scala, you can create recursive functions also. Be careful while using recursive function. There must be a base condition to
terminate program safely.
object Test {
def main(args: Array[String]) = {
var result = Testfunction(15,2)
println(result)
}
def Testfunction(a:Int, b:Int):Int = {
if(b == 0) // Base condition
0
else
a+Testfunction(a,b-1)
}
}
Scala Function Parameter Example with default value:
object Test {
def main(args: Array[String]) = {
var result1 = Testfunction(15,2) // Calling with two values
var result2 = Testfunction(15) // Calling with one value
var result3 = Testfunction() // Calling without any value
println(result1+"\n"+result2+"\n"+result3)
}
def Testfunction(a:Int = 0, b:Int = 0):Int = {
a+b
}
}
In scala function, you can specify the names of parameters during calling the function. In the given example, you can notice
that parameter names are passing during calling. You can pass named parameters in any order and can also pass values
only.
object Test {
def main(args: Array[String]) = {
var result1 = Testfunction(a = 15, b = 2) // Parameters names are passed during call
var result2 = Testfunction(b = 15, a = 2) // Parameters order have changed during call
var result3 = Testfunction(15,2) // Only values are passed during call
println(result1+"\n"+result2+"\n"+result3)
}
def Testfunction(a:Int, b:Int):Int = {
a+b
}
}
Scala Collection:
Scala provides rich set of collection library. It contains classes and traits to collect data. These collections can be
mutable or immutable. You can use them according to your requirement. Scala.collection.mutable package contains all
the mutable collections. You can add, remove and update data while using this package.
Scala.collection.immutable contains all the immutable collections. It does not allow you to modify data. Scala imports
this package by default. If you want mutable collection, you must import scala.collection.mutable package in your
code.
Scala Immutable Collections Hierarchy:
The scala.collection.immutable package contains all the immutable abstract classes and traits for collections.
Scala Traversable
It is a trait and used to traverse collection elements. It is a base trait for all scala collections.
def isEmpty: Boolean It checks whether the collection is empty or not. It returns either true or
false.
def size: Int It is used to get size of this traversable and returns a number of elements
present in this traversable.
A trait is like an interface with a partial implementation. In scala, trait is a collection of abstract and non-abstract
methods. You can create trait that can have all abstract methods or some abstract and some non-abstract methods.
A variable that is declared either by using val or var keyword in a trait get internally implemented in the class that
implements the trait. Any variable which is declared by using val or var but not initialized is considered abstract.
Traits are compiled into Java interfaces with corresponding implementation classes that hold any methods implemented
in the traits.
Example:
trait Printable{
def print()
}
class A4 extends Printable{
def print(){
println("Hello")
}
}
object MainObject{
def main(args:Array[String]){
var a = new A4()
a.print()
}
}
If a class extends a trait but does not implement the members declared in that trait, it must be declared abstract. Let's
see an example.
trait Printable{
def print()
}
abstract class A4 extends Printable{ // Must declared as abstract class
def printA4(){
println("Hello World")
}
}
Scala List
List is used to store ordered elements. It is a class for immutable linked lists. This class is good for last-in-first-out (LIFO),
stack-like access patterns.
import scala.collection.immutable._
object MainObject{
def main(args:Array[String]){
var temp = List(1,8,5,6,9,58,23,15,4)
var temp1:List[Int] = List(1,8,5,6,9,58,23,15,4)
println(temp)
println(temp1)
}
}
Applying Predefined Methods in List
import scala.collection.immutable._
object MainObject{
def main(args:Array[String]){
var list = List(1,8,5,6,9,58,23,15,4)
var list2 = List(88,100)
print("Elements: ")
list.foreach((element:Int) => print(element+" ")) // Iterating using foreach loop
print("\nElement at 2 index: "+list(2)) // Accessing element of 2 index
var list3 = list ++ list2 // Merging two list
print("\nElement after merging list and list2: ")
list3.foreach((element:Int)=>print(element+" "))
var list4 = list3.sorted // Sorting list
print("\nElement after sorting list3: ")
list4.foreach((element:Int)=>print(element+" "))
var list5 = list3.reverse // Reversing list elements
print("\nElements in reverse order of list5: ")
list5.foreach((element:Int)=>print(element+" "))
}
}
Scala Maps:
Map is used to store elements. It stores elements in pairs of key and values. In scala, you can create map by using two ways
either by using comma separated pairs or by using rocket operator.
object Temp{
def main(args:Array[String]){
var map = Map(("A","Apple"),("B","Ball"))
var map2 = Map("A"->"Apple","B"->"Ball")
var emptyMap:Map[String,String] = Map.empty[String,String]
println(map)
println(map2)
println("Empty Map: "+emptyMap)
}
}
Output:
You can add and remove new elements in maps. Scala provides you lots of predefined method. You can use them to
perform operations on the Maps. In the following example, we have created a new Map.
object Temp{
def main(args:Array[String]){
var map = Map("A"->"Apple","B"->"Ball") // Creating map
println(map("A")) // Accessing value by using key
var newMap = map+("C"->"Cat") // Adding a new element to map
println(newMap)
var removeElement = newMap - ("B") // Removing an element from map
println(removeElement)
}
}
Output:
Apple
Map(A -> Apple, B -> Ball, C -> Cat)
Map(A -> Apple, C -> Cat)
Scala Stream
Stream is a lazy list. It evaluates elements only when they are required. This is a feature of scala. Scala supports lazy
computation. It increases performance of your program.
Example:
object Test{
def main(args:Array[String]){
val stream = 100 #:: 200 #:: 85 #:: Stream.empty
println(stream)
}
}
Output:
Stream(100, ?)
In the output, you can see that second element is not evaluated. Here, a question mark is displayed in place of element.
Scala does not evaluate list until it is required.
Applying Predefined Methods:
In the following example, we have used some predefined methods like toStream, which is used to iterate
stream elements.
import scala.collection.immutable._
object MainObject{
def main(args:Array[String]){
var stream = 100 #:: 200 #:: 85 #:: Stream.empty
println(stream)
var stream2 = (1 to 10).toStream
println(stream2)
var firstElement = stream2.head
println(firstElement)
println(stream2.take(10))
println(stream.map{_*2})
}
}
Output:
Stream(100, ?)
Stream(1, ?)
1
Stream(1, ?)
Stream(200, ?)