Scala Quick Notes :: Part - 8


Bhaskar S 02/28/2015


Overview

In this part of the series, we will look at using Higher-Order functions with Scala Collections, explore Scala Implicit arguments and conversions, and explore basic Scala Concurrency options.

Hands-on With Scala - VIII

The following is the Scala program named Sample26.scala:

Sample26.scala
/*
 *
 * Name  : Sample26
 * 
 * Author: Bhaskar S
 *  
 * Date  : 02/27/2015
 *  
 */

package com.polarsparc.scala

object Sample26 {
  def main(args: Array[String]) = {
    val list = List(5, 10, 15, 20, 25, 30)
    val set = Set("Acura", "Audi", "BMW", "Jaguar", "Lexus", "Mercedes")
    val map = Map("AAPL" -> 128, "CSCO" -> 27, "GOOG" -> 560, "INTC" -> 35, "MSFT" -> 42, "ORCL" -> 35)
    
    println("list = " + list)
    println("set = " + set)
    println("map = " + map)
    
    val ls1 = list.filter((a: Int) => a % 2 == 0)
    val st1 = set.filter((a: String) => a.length() <= 4)
    val mp1 = map.filter((a) => a._2 > 100)
    
    println("ls1 = " + ls1)
    println("st1 = " + st1)
    println("mp1 = " + mp1)
    
    val ls2 = list.filter(_ % 2 == 0)
    val st2 = set.filter(_.length <= 4)
    val mp2 = map.filter(_._2 > 100)
    
    println("ls2 = " + ls2)
    println("st2 = " + st2)
    println("mp2 = " + mp2)
    
    val ls3 = list.map(_ / 5)
    val st3 = set.map(_.length)
    val mp3 = map.map((a) => (a._1, a._2+5))
    
    println("ls3 = " + ls3)
    println("st3 = " + st3)
    println("mp3 = " + mp3)
    
    val sum1 = list.reduce((a: Int, b: Int) => a + b)
    val con1 = set.reduce((a: String, b: String) => a + ", " + b)
    
    println("sum1 = " + sum1)
    println("con1 = " + con1)
    
    val sum2 = list.reduce(_ + _)
    val con2 = set.reduce(_ + ", " + _)
    
    println("sum2 = " + sum2)
    println("con2 = " + con2)
    
    val sum3 = list.fold(0)(_ + _)
    val con3 = set.fold("->")(_ + " | " + _)
    
    println("sum3 = " + sum3)
    println("con3 = " + con3)
  }
}

Executing the program Sample26.scala results in the output:

Output (Sample26.scala)

list = List(5, 10, 15, 20, 25, 30)
set = Set(Audi, Mercedes, Lexus, Jaguar, BMW, Acura)
map = Map(MSFT -> 42, AAPL -> 128, ORCL -> 35, INTC -> 35, GOOG -> 560, CSCO -> 27)
ls1 = List(10, 20, 30)
st1 = Set(Audi, BMW)
mp1 = Map(AAPL -> 128, GOOG -> 560)
ls2 = List(10, 20, 30)
st2 = Set(Audi, BMW)
mp2 = Map(AAPL -> 128, GOOG -> 560)
ls3 = List(1, 2, 3, 4, 5, 6)
st3 = Set(5, 6, 3, 8, 4)
mp3 = Map(MSFT -> 47, AAPL -> 133, ORCL -> 40, INTC -> 40, GOOG -> 565, CSCO -> 32)
sum1 = 105
con1 = Audi, Mercedes, Lexus, Jaguar, BMW, Acura
sum2 = 105
con2 = Audi, Mercedes, Lexus, Jaguar, BMW, Acura
sum3 = 105
con3 = -> | Audi | Mercedes | Lexus | Jaguar | BMW | Acura

The following section explains some of the aspects of the Scala program Sample26.scala:

The following is the Scala program named Sample27.scala:

Sample27.scala
/*
 *
 * Name  : Sample27
 * 
 * Author: Bhaskar S
 *  
 * Date  : 02/27/2015
 *  
 */

package com.polarsparc.scala

object Sample27 {
  def main(args: Array[String]) = {
    def logger(a: String)(implicit b: String) = printf(s"${b} :: ${a}\n")
    
    {
      logger("Welcome to Scala")("DEBUG")
      
      // logger("Hello Scala Implicit !!!") -- This will generate a compiler error
    }
    
    {
      implicit val level = "INFO"
      
      logger("Hello Scala Implicit !!!")
    }
    
    {
      implicit val level1 = "INFO"
      implicit val level2 = "WARN"
        
      print("")
      
      // logger("Hello Scala Implicit !!!") -- This will generate a compiler error
    }
    
    class Fraction(val num: Int, val den: Int) {
	  private def modDen(other: Fraction) = den * other.den
		  
	  def + (other: Fraction): Fraction = {
	    val mnum = num * other.den + den * other.num
	    new Fraction(mnum, modDen(other))
	  }
		  
	  def * (other: Fraction): Fraction = new Fraction(num * other.num, modDen(other))
		    
	  override def toString = num + "/" + den
	}
    
    val fr = new Fraction(1, 2)
    
    {
      print("")
      // printf("5 + fr = %s\n", 5 + fr) -- This will generate a compiler error
    }
    
    {
		implicit def int2Fraction(a: Int) = new Fraction(a, 1)
		
		printf("[1] int2Fraction(5) + %s = %s\n", fr, int2Fraction(5) + fr)
		printf("[2] 5 + %s = %s\n", fr, 5 + fr)
    }
  }
}

Executing the program Sample27.scala results in the output:

Output (Sample27.scala)

DEBUG :: Welcome to Scala
INFO :: Hello Scala Implicit !!!
[1] int2Fraction(5) + 1/2 = 11/2
[2] 5 + 1/2 = 11/2

The following section explains some of the aspects of the Scala program Sample27.scala:

The following is the Scala program named Sample28.scala:

Sample28.scala
/*
 *
 * Name  : Sample28
 * 
 * Author: Bhaskar S
 *  
 * Date  : 02/27/2015
 *  
 */

package com.polarsparc.scala

import java.util.concurrent.Executors
import java.util.concurrent.ExecutorService

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}

object Sample28 {
  def main(args: Array[String]) = {
    def execute(a: Runnable)(implicit b: ExecutorService) = b.execute(a)
    
    {
      implicit val defThreadPool = java.util.concurrent.Executors.newFixedThreadPool(5)
      
      execute(new Runnable {
        override def run() {
          printf("%s: Am thread one executing ...\n", Thread.currentThread().getName())
        }
      })
      
      execute(new Runnable {
        override def run() {
          printf("%s: Am thread two executing ...\n", Thread.currentThread().getName())
        }
      })
      
      Thread.sleep(1000)
      
      defThreadPool.shutdown()
    }
    
    {
      def factorial(n: Int): BigInt = {
        if (n > 100) throw new Exception("Stack Error")
        
        if (n < 2) 1 else n*factorial(n-1)
      }
      
      val fac5 = Future {
        Thread.sleep(5000);
        factorial(5)
      }
      
      fac5.onSuccess {
        case res => printf(s"onSuccess:: Factorial of 5 = ${res}\n")
      }
      
      fac5.onFailure {
        case exc => printf("onFailure:: Exception for Factorial of 5 :: %s\n", exc.getMessage())
      }
      
      val fac10 = Future {
        Thread.sleep(5000);
        factorial(10)
      }
      
      fac10.onComplete {
        case Success(res) => printf(s"onComplete:: Factorial of 10 = ${res}\n")
        case Failure(exc) => printf("onComplete:: Exception for Factorial of 10 :: %s\n", exc.getMessage())
      }
      
      println("Waiting for factorial 5 and 10 results .....")
      
      Thread.sleep(15000);
      
      println("Done with factorial 5 and 10 !!!")
      
      val fac101 = Future {
        Thread.sleep(5000);
        factorial(101)
      }
      
      println("Waiting for factorial 101 results .....")
      
      fac101.onSuccess {
        case res => printf(s"onSuccess:: Factorial of 101 = ${res}\n")
      }
      
      fac101.onFailure {
        case exc: Exception => printf("onFailure:: Exception for Factorial of 101 :: %s\n", exc.getMessage())
      }
      
      Thread.sleep(15000);
      
      println("Done with factorial 101 !!!")
    }
  }
}

Executing the program Sample28.scala results in the output:

Output (Sample28.scala)

pool-1-thread-2: Am thread two executing ...
pool-1-thread-1: Am thread one executing ...
Waiting for factorial 5 and 10 results .....
onSuccess:: Factorial of 5 = 120
onComplete:: Factorial of 10 = 3628800
Done with factorial 5 and 10 !!!
Waiting for factorial 101 results .....
onFailure:: Exception for Factorial of 101 :: Stack Error
Done with factorial 101 !!!

The following section explains some of the aspects of the Scala program Sample28.scala:

References

Scala Quick Notes :: Part - 1

Scala Quick Notes :: Part - 2

Scala Quick Notes :: Part - 3

Scala Quick Notes :: Part - 4

Scala Quick Notes :: Part - 5

Scala Quick Notes :: Part - 6

Scala Quick Notes :: Part - 7