Introduction to Scala

Updated examples
This commit is contained in:
chandra 2018-10-24 16:43:09 -04:00
parent d074cdd76a
commit 464189ff4e
13 changed files with 291 additions and 158 deletions

4
.gitignore vendored
View File

@ -63,4 +63,6 @@ jmeter/src/main/resources/*-JMeter.csv
**/tmp **/tmp
**/out-tsc **/out-tsc
**/nbproject/ **/nbproject/
**/nb-configuration.xml **/nb-configuration.xml
core-scala/.cache-main
core-scala/.cache-tests

View File

@ -47,7 +47,7 @@
</build> </build>
<properties> <properties>
<scala.version>2.11.8</scala.version> <scala.version>2.12.7</scala.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,44 @@
package com.baeldung.scala
/**
* Sample code demonstrating the various control structured.
*
* @author Chandra Prakash
*
*/
object ControlStructuresDemo {
def gcd(x : Int, y : Int) : Int = {
if (y == 0) x else gcd(y, x % y)
}
def gcdIter(x : Int, y : Int) : Int = {
var a = x
var b = y
while (b > 0) {
a = a % b
val t = a
a = b
b = t
}
a
}
def rangeSum(a : Int, b : Int) = {
var sum = 0;
for (i <- a to b) {
sum += i
}
sum
}
def factorial(a : Int) : Int = {
var result = 1;
var i = 1;
do {
result *= i
i = i + 1
} while (i <= a)
result
}
}

View File

@ -1,10 +1,27 @@
package com.baeldung.scala package com.baeldung.scala
class Employee(val name: String, var salary: Int, annualIncrement: Int = 20) extends AnyRef { /**
* Sample Code demonstrating a class.
*
* @author Chandra Prakash
*
*/
class Employee(val name : String,
var salary : Int,
annualIncrement : Int = 20) {
def incrementSalary(): Unit = { def incrementSalary() : Unit = {
salary += annualIncrement salary += annualIncrement
} }
override def toString =
s"Employee(name=$name, salary=$salary)"
}
/**
* A Trait which will make the toString return upper case value.
*/
trait UpperCasePrinter {
override def toString = super.toString toUpperCase
}
override def toString = s"Employee(name=$name, salary=$salary)"
}

View File

@ -1,6 +1,6 @@
package com.baeldung.scala package com.baeldung.scala
object HelloWorld extends App { object HelloWorld extends App {
println("Hello World!") println("Hello World!")
args foreach println args foreach println
} }

View File

@ -1,14 +1,27 @@
package com.baeldung.scala package com.baeldung.scala
/**
* Sample higher order functions.
*
* @author Chandra Prakash
*
*/
object HigherOrderFunctions { object HigherOrderFunctions {
def mapReduce(r: (Int, Int) => Int, i: Int, m: Int => Int, a: Int, b: Int) = { def mapReduce(r : (Int, Int) => Int,
def iter(a: Int, result: Int): Int = { i : Int,
if (a > b) result m : Int => Int,
else iter(a + 1, r(m(a), result)) a : Int, b : Int) = {
} def iter(a : Int, result : Int) : Int = {
iter(a, i) if (a > b) result
else iter(a + 1, r(m(a), result))
}
iter(a, i)
}
def whileLoop(condition : => Boolean)(body : => Unit) : Unit =
if (condition) {
body
whileLoop(condition)(body)
} }
} }

View File

@ -0,0 +1,34 @@
package com.baeldung.scala
/**
* An abstract class for set of integers and its implementation.
*
* @author Chandra Prakash
*
*/
abstract class IntSet {
// add an element to the set
def incl(x : Int) : IntSet
// whether an element belongs to the set
def contains(x : Int) : Boolean
}
class EmptyIntSet extends IntSet {
def contains(x : Int) : Boolean = false
def incl(x : Int) =
new NonEmptyIntSet(x, this)
}
class NonEmptyIntSet(val head : Int, val tail : IntSet)
extends IntSet {
def contains(x : Int) : Boolean =
head == x || (tail contains x)
def incl(x : Int) : IntSet =
if (this contains x) this
else new NonEmptyIntSet(x, this)
}

View File

@ -1,66 +1,33 @@
package com.baeldung.scala package com.baeldung.scala
/**
* Some utility methods.
*
* @author Chandra Prakash
*
*/
object Utils { object Utils {
def average(x: Double, y: Double) = (x + y) / 2 def average(x : Double, y : Double) = (x + y) / 2
def gcd(x: Int, y: Int): Int = { def randomLessThan(d : Double) = {
if (y == 0) x else gcd(y, x % y) var random = 0d
do {
random = Math.random()
} while (random >= d)
random
}
def power(x : Int, y : Int) : Int = {
def powNested(i : Int, accumulator : Int) : Int = {
if (i <= 0) accumulator
else powNested(i - 1, x * accumulator)
} }
powNested(y, 1)
}
def gcdIter(x: Int, y: Int): Int = { def fibonacci(n : Int) : Int = n match {
var a = x case 0 | 1 => 1
var b = y case x if x > 1 =>
while (b > 0) { fibonacci(x - 1) + fibonacci(x - 2)
a = a % b }
val t = a
a = b
b = t
}
return a
}
def rangeSum(a: Int, b: Int) = {
var sum = 0;
for (i <- a to b) {
sum += i
}
sum
}
def factorial(a: Int): Int = {
var result = 1;
var i = a;
do {
result *= i
i = i - 1
} while (i > 0)
result
}
def randomLessThan(d: Double) = {
var random = 0d
do {
random = Math.random()
} while (random >= d)
random
}
def whileLoop(condition: => Boolean)(body: => Unit): Unit =
if (condition) {
body
whileLoop(condition)(body)
}
def power(x: Int, y: Int): Int = {
def powNested(i: Int, accumulator: Int): Int = {
if (i <= 0) accumulator
else powNested(i - 1, x * accumulator)
}
powNested(y, 1)
}
def fibonacci(n: Int): Int = n match {
case 0 | 1 => 1
case x if x > 1 => fibonacci(x - 1) + fibonacci(x - 2)
}
} }

View File

@ -0,0 +1,33 @@
package com.baeldung.scala
import com.baeldung.scala.ControlStructuresDemo._
import org.junit.Test
import org.junit.Assert.assertEquals
class ControlStructuresDemoUnitTest {
@Test
def givenTwoIntegers_whenGcdCalled_thenCorrectValueReturned = {
assertEquals(3, gcd(15, 27))
}
@Test
def givenTwoIntegers_whenGcdIterCalled_thenCorrectValueReturned = {
assertEquals(3, gcdIter(15, 27))
}
@Test
def givenTwoIntegers_whenRangeSumcalled_thenCorrectValueReturned = {
assertEquals(55, rangeSum(1, 10))
}
@Test
def givenPositiveInteger_whenFactorialInvoked_thenCorrectValueReturned = {
assertEquals(720, factorial(6))
}
@Test
def whenFactorialOf0Invoked_then1Returned = {
assertEquals(1, factorial(0))
}
}

View File

@ -1,22 +1,30 @@
package com.baeldung.scala package com.baeldung.scala
import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
import org.junit.Assert._
class EmployeeUnitTest { class EmployeeUnitTest {
@Test @Test
def whenEmployeeSalaryIncremented_thenCorrectSalary() = { def whenEmployeeSalaryIncremented_thenCorrectSalary = {
val employee = new Employee("John Doe", 1000); val employee = new Employee("John Doe", 1000)
employee.incrementSalary(); employee.incrementSalary()
assertEquals(1020, employee.salary); assertEquals(1020, employee.salary)
} }
@Test
def givenEmployee_whenToStringCalled_thenCorrectStringReturned = {
val employee = new Employee("John Doe", 1000)
assertEquals("Employee(name=John Doe, salary=1000)", employee.toString)
}
@Test
def givenEmployeeWithTrait_whenToStringCalled_thenCorrectStringReturned = {
val employee =
new Employee("John Doe", 1000) with UpperCasePrinter
assertEquals("EMPLOYEE(NAME=JOHN DOE, SALARY=1000)", employee.toString)
}
@Test
def givenEmployee_whenToStringCalled_thenCorrectStringReturned() = {
val employee = new Employee("John Doe", 1000);
assertEquals("Employee(name=John Doe, salary=1000)", employee.toString);
}
} }

View File

@ -1,44 +1,49 @@
package com.baeldung.scala package com.baeldung.scala
import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
import org.junit.Assert._
import HigherOrderFunctions._ import HigherOrderFunctions.mapReduce
class HigherOrderFunctionsUnitTest { class HigherOrderFunctionsUnitTest {
@Test @Test
def whenCalledWithSumAndSquareFunctions_thenCorrectValueReturned = { def whenCalledWithSumAndSquareFunctions_thenCorrectValueReturned = {
def square(x: Int) = x * x def square(x : Int) = x * x
def sum(x: Int, y: Int) = x + y def sum(x : Int, y : Int) = x + y
def sumSquares(a: Int, b: Int) = def sumSquares(a : Int, b : Int) =
mapReduce(sum, 0, square, a, b) mapReduce(sum, 0, square, a, b)
val n = 10 assertEquals(385, sumSquares(1, 10))
val expected = n * (n + 1) * (2 * n + 1) / 6 }
assertEquals(expected, sumSquares(1, n));
}
@Test @Test
def whenComputingSumOfSquaresWithAnonymousFunctions_thenCorrectValueReturned = { def whenComputingSumOfSquaresWithAnonymousFunctions_thenCorrectValueReturned = {
def sumSquares(a: Int, b: Int) = def sumSquares(a : Int, b : Int) =
mapReduce((x, y) => x + y, 0, x => x * x, a, b) mapReduce((x, y) => x + y, 0, x => x * x, a, b)
val n = 10 assertEquals(385, sumSquares(1, 10))
val expected = n * (n + 1) * (2 * n + 1) / 6 }
assertEquals(expected, sumSquares(1, n));
}
@Test @Test
def givenCurriedFunctions_whenInvoked_thenCorrectValueReturned = { def givenCurriedFunctions_whenInvoked_thenCorrectValueReturned = {
def sum(f: Int => Int)(a: Int, b: Int): Int = // a curried function
if (a > b) 0 else f(a) + sum(f)(a + 1, b) def sum(f : Int => Int)(a : Int,
b : Int) : Int =
if (a > b) 0 else f(a) + sum(f)(a + 1, b)
def mod(n: Int)(x: Int) = x % n // another curried function
def mod(n : Int)(x : Int) = x % n
def sumMod5 = sum(mod(5)) _ // application of a curried function
assertEquals(1, mod(5)(6))
assertEquals(10, sumMod5(6,10));
} // partial application of curried function
// trailing underscore is required to make function type explicit
val sumMod5 = sum(mod(5)) _
assertEquals(10, sumMod5(6, 10))
}
} }

View File

@ -0,0 +1,23 @@
package com.baeldung.scala
import scala.Range
import org.junit.Assert.assertFalse
import org.junit.Test
class IntSetUnitTest {
@Test
def givenSetof1To10_whenContains11Called_thenFalse = {
// Set up a set containing integers 1 to 10.
val set1To10 =
Range(1, 10)
.foldLeft(new EmptyIntSet() : IntSet) {
(x, y) => x incl y
}
assertFalse(set1To10 contains 11)
}
}

View File

@ -1,50 +1,37 @@
package com.baeldung.scala package com.baeldung.scala
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
import Utils._
import org.junit.Assert._ import Utils.average
import Utils.fibonacci
import Utils.power
import Utils.randomLessThan
class UtilsUnitTest { class UtilsUnitTest {
@Test @Test
def whenAverageCalled_thenCorrectValueReturned() = { def whenAverageCalled_thenCorrectValueReturned() = {
val average = Utils.average(10, 20) assertEquals(15.0, average(10, 20), 1e-5)
assertEquals(15.0, average, 1e-5) }
}
@Test @Test
def givenTwoIntegers_whenGcdCalled_thenCorrectValueReturned = { def whenRandomLessThanInvokedWithANumber_thenARandomLessThanItReturned = {
assertEquals(3, Utils.gcd(15, 27)) val d = 0.1
} assertTrue(randomLessThan(d) < d)
}
@Test @Test
def givenTwoIntegers_whenGcdIterCalled_thenCorrectValueReturned = { def whenPowerInvokedWith2And3_then8Returned = {
assertEquals(3, Utils.gcdIter(15, 27)) assertEquals(8, power(2, 3))
} }
@Test @Test
def givenTwoIntegers_whenRangeSumcalled_thenCorrectValueReturned = { def whenFibonacciCalled_thenCorrectValueReturned = {
assertEquals(55, Utils.rangeSum(1, 10)) assertEquals(1, fibonacci(0))
} assertEquals(1, fibonacci(1))
assertEquals(fibonacci(6),
@Test fibonacci(4) + fibonacci(5))
def givenPositiveInteger_whenFactorialInvoked_thenCorrectValueReturned = { }
assertEquals(720, Utils.factorial(6))
}
@Test
def whenRandomLessThanInvokedWithANumber_thenARandomLessThanItReturned = {
val d = 0.1
assertTrue(Utils.randomLessThan(d) < d)
}
@Test
def whenPowerInvokedWith2And3_then8Returned = {
assertEquals(8, power(2, 3))
}
@Test
def whenFibonacciCalled_thenCorrectValueReturned = {
assertEquals(34, fibonacci(8))
}
} }