Slide 1

Slide 1 text

Scala for Java Developers It is simpler than you think Peter Gabryanczyk @piotrga [email protected] http://blog.scala4java.com

Slide 2

Slide 2 text

package scala4java object Area{ } Hello World

Slide 3

Slide 3 text

package scala4java object Area{ def main(args: Array[String]){ } } Hello World

Slide 4

Slide 4 text

package scala4java object Area{ def main(args: Array[String]){ var width = args(0).toDouble } } Hello World

Slide 5

Slide 5 text

var width = args(0).toDouble Is equivalent to: var width : Double = args(0).toDouble Type inference

Slide 6

Slide 6 text

package scala4java object Area{ def main(args: Array[String]){ var width = args(0).toDouble } } Hello World

Slide 7

Slide 7 text

package scala4java object Area{ def main(args: Array[String]){ var width = args.apply(0).toDouble } } Hello World

Slide 8

Slide 8 text

package scala4java object Area{ def main(args: Array[String]){ var width = args(0).toDouble } } Hello World

Slide 9

Slide 9 text

package scala4java object Area{ def main(args: Array[String]){ var width = args(0).toDouble println("Area = " + width * width ) } } Hello World

Slide 10

Slide 10 text

Running Scala Program

Slide 11

Slide 11 text

class Square{ def area(width : Double) : Double = { width * width } } var square = new Square square.area 10 -> 100 Classes

Slide 12

Slide 12 text

def area(width : Double) : Double = { return width * width } Classes

Slide 13

Slide 13 text

def area(width : Double) : Double = { return width * width } def area(width : Double) : Double = { width * width } Classes

Slide 14

Slide 14 text

def area(width : Double) : Double = { return width * width } def area(width : Double) : Double = { width * width } def area(width : Double) = { width * width } Classes

Slide 15

Slide 15 text

def area(width : Double) : Double = { return width * width } def area(width : Double) : Double = { width * width } def area(width : Double) = { width * width } def area(width : Double) = width * width Classes

Slide 16

Slide 16 text

public class Square{ public Double area(Double width){ return width * width; } } vs class Square{ def area(width:Double) = width * width } Java vs Scala

Slide 17

Slide 17 text

public class Square{ private Double width; private final String name; public Square(width : Double, color : String){ this.width = width; name = color+" square of width "+ width System.out.println("Creating " + name) } ... } Constructor

Slide 18

Slide 18 text

class Square(width : Double, color : String){ var name = color+" square of width "+ width println("Creating " + name) def area() = width * width override def toString = name } var sq = new Square(10, "blue") Constructor

Slide 19

Slide 19 text

class Square(width : Double, color : String){ var name = color+" square of width "+ width println("Creating " + name) def area() = width * width override def toString = name } var sq = new Square(10, "blue") Constructor Params

Slide 20

Slide 20 text

class Square(width : Double, color : String){ var name = color+" square of width "+ width println("Creating " + name) def area() = width * width override def toString = name } var sq = new Square(10, "blue") Constructor Params

Slide 21

Slide 21 text

class Square(width : Double, color : String){ var name = color+" square of width "+ width println("Creating " + name) def area() = width * width override def toString = name } Members

Slide 22

Slide 22 text

class Square(width : Double, color : String){ val name = color+" square of width "+ width println("Creating " + name) def area() = width * width override def toString = name } val ~= final

Slide 23

Slide 23 text

class Square(width : Double, color : String){ var name = color+" square of width "+ width println("Creating " + name) def area = width * width override def toString = name } var sq = new Square(10, "blue") -> Creating blue square of width 10.0 -> sq: Square = blue square of width 10.0 Body is constructor

Slide 24

Slide 24 text

class Square(width : Double, color : String){ var name = color+" square of width "+ width println("Creating " + name) def area() = width * width override def toString = name } can be simplified to: class Square(width : Double, color : String){ def area = width * width override def toString = color + " square of width " + width } Constructor

Slide 25

Slide 25 text

public class Square{ final Double width; final String color; public Square(Double width, String color){ this.width = width; this.color = color; } public Double area(){ return width * width; } public String toString(){ return color + " square of width " + width; } } vs class Square(width : Double, color : String){ def area = width * width override def toString = color + " square of width " + width } Java vs Scala

Slide 26

Slide 26 text

class Square(originalWidth : Double){ private var widthInternal = originalWidth def width = widthInternal def width_=(newWidth : Double) = { widthInternal = newWidth } def area = widthInternal * widthInternal } var square = new Square(10) square.width = 9999 println(square.width) -> 9999 Properties

Slide 27

Slide 27 text

class Square(var width: Double){ def area = width * width } var square = new Square(10) square.width = 9999 println(square.width) -> 9999 Properties

Slide 28

Slide 28 text

class Shape(_color : String){ protected def color = _color } class Square(width : Double) extends Shape("black"){ def area = width * width override def toString = color + " square of " + width + "cm" } Inheritance

Slide 29

Slide 29 text

class Shape(_color : String){ protected def color = _color } class Square(width : Double) extends Shape("black"){ def area = width * width override def toString = color + " square of " + width + "cm" } Inheritance

Slide 30

Slide 30 text

SBT Simple Build Tool

Slide 31

Slide 31 text

abstract class Shape case class Square(width : Double) extends Shape case class Rectangle(width : Double, height : Double) extends Shape case class Circle(radius : Double) extends Shape Case Classes

Slide 32

Slide 32 text

var x = Rectangle(10, 20) Case Classes

Slide 33

Slide 33 text

var x = Rectangle(10, 20) println(x.width) -> 10.0 Case Classes

Slide 34

Slide 34 text

var x = Rectangle(10, 20) println(x.width) -> 10.0 println(x) -> Rectangle(10.0,20.0) Case Classes

Slide 35

Slide 35 text

var x = Rectangle(10, 20) println(x.width) -> 10.0 println(x) -> Rectangle(10.0,20.0) Rectangle(10,20) == Rectangle(1+9, 21 -1) -> true Rectangle(10,20).hashCode == Rectangle(1+9, 21 -1).hashCode -> true Case Classes

Slide 36

Slide 36 text

var x = Rectangle(10, 20) println(x.width) -> 10.0 println(x) -> Rectangle(10.0,20.0) Rectangle(10,20) == Rectangle(1+9, 21 -1) -> true Rectangle(10,20).hashCode == Rectangle(1+9, 21 -1).hashCode -> true x match{ case Circle(r) => println (“Circle with radius “ + r) case Rectangle(w, h) => ... } Case Classes

Slide 37

Slide 37 text

trait Paintable{ def area : Double // abstract method def costOfPainting(paintPrice : Double) = area * paintPrice } Traits

Slide 38

Slide 38 text

trait Paintable{ def area : Double // abstract method def costOfPainting(paintPrice : Double) = area * paintPrice } trait Externalizable{ def externalize(out : Writer) } Traits

Slide 39

Slide 39 text

trait Paintable{ def area : Double // abstract method def costOfPainting(paintPrice : Double) = area * paintPrice } trait Externalizable{ def externalize(out : Writer) } class Square(width : Double) extends Paintable with Externalizable{ def area() = width * width def externalize(out: Writer) = out.write("SQUARE[%f]".format(width)) } Traits

Slide 40

Slide 40 text

class Circle(r : Double) { def area = 3.14 * r * r} var tableSurface = new Circle(5) with Paintable tableSurface costOfPainting 10 -> 785 Traits

Slide 41

Slide 41 text

if(true){ println("True") }else{ println("False") } if(false) println("True") else println("False") val max = if(a > b) a else b If Statement

Slide 42

Slide 42 text

var i = 0 while(i < 10){ println(i) i += 1 } var j = 10 do{ println(j) j += 1 }while(j<10) While

Slide 43

Slide 43 text

for (i <- 1 to 3){ println(i) } For

Slide 44

Slide 44 text

println(1 to 3) -> Range(1,2,3) println(1 to(3)) -> Range(1,2,3) println(1.to(3)) -> Range(1,2,3) Infix Notation

Slide 45

Slide 45 text

for (i <- List(1,3,5,7,11)) println(i) for (i <- 1 to 3) println(i) Class with foreach

Slide 46

Slide 46 text

scala> val squares = for (i <- 1 to 3) yield i*i scala> println(squares) Vector(1, 4, 9) Yield

Slide 47

Slide 47 text

scala> val evens = for (i <- 1 to 10 if( i % 2 == 0)) yield i scala> println(evens) Vector(2, 4, 6, 8, 10) Filters

Slide 48

Slide 48 text

for (i <- 1 to 10 modulo2 = i % 2 if( modulo2 == 0) ) yield i Temporary variables

Slide 49

Slide 49 text

scala> val product = for (i <- 1 to 2 j <- 'a' to 'b' ) yield (i, j) scala> println(product) Vector((1,a), (1,b), (2,a), (2,b)) Multiple generators = product

Slide 50

Slide 50 text

scala> for( (i,j) <- List((1, 2),(10, 20))) yield i*j List(2, 200) Pattern Matching

Slide 51

Slide 51 text

Scala Console

Slide 52

Slide 52 text

// Importing class HashMap import scala.collection.immutable.HashMap Imports

Slide 53

Slide 53 text

// Importing class HashMap import scala.collection.immutable.HashMap // Importing whole content of package scala.collection import scala.collection._ Imports

Slide 54

Slide 54 text

// Importing class HashMap import scala.collection.immutable.HashMap // Importing whole content of package scala.collection import scala.collection._ // Importing all members of object HashSet - similar to static import in java import scala.collection.immutable.HashSet._ Imports

Slide 55

Slide 55 text

// Importing class HashMap import scala.collection.immutable.HashMap // Importing whole content of package scala.collection import scala.collection._ // Importing all members of object HashSet - similar to static import in java import scala.collection.immutable.HashSet._ // Importing Actor and Channel from package scala.actor import scala.actors.{Actor, Channel} Imports

Slide 56

Slide 56 text

// Importing java.lang.Boolean and aliasing it as JavaBoolean import java.lang.{Boolean => JavaBoolean} Imports - advanced

Slide 57

Slide 57 text

// Importing java.lang.Boolean and aliasing it as JavaBoolean import java.lang.{Boolean => JavaBoolean} object Imports{ // We can use JavaBoolean as we would used the Boolean var bool = new JavaBoolean(true) print(bool) } Imports - advanced

Slide 58

Slide 58 text

// Importing java.lang.Boolean and aliasing it as JavaBoolean import java.lang.{Boolean => JavaBoolean} object Imports{ // We can use JavaBoolean as we would used the Boolean var bool = new JavaBoolean(true) print(bool) class SomeInnerClass{ // This import is only visible inside of SomeInnerClass import scala.concurrent.TaskRunners val runner = TaskRunners.threadRunner //... } } Imports - advanced

Slide 59

Slide 59 text

// Importing java.lang.Boolean and aliasing it as JavaBoolean import java.lang.{Boolean => JavaBoolean} object Imports{ // We can use JavaBoolean as we would used the Boolean var bool = new JavaBoolean(true) print(bool) class SomeInnerClass{ // This import is only visible inside of SomeInnerClass import scala.concurrent.TaskRunners val runner = TaskRunners.threadRunner //... } // Imports can be declared anywhere import java.io.File new File("a.txt") } Imports - advanced

Slide 60

Slide 60 text

def convert(list : List[String], converter : String => Int ) = { for(e <- list) yield converter(e) } Functions: Type

Slide 61

Slide 61 text

def convert(list : List[String], converter : String => Int ) = { for(e <- list) yield converter(e) } val numbers = List("1", "2") def simpleConverter(s:String) = s.toInt convert(numbers, simpleConverter) Functions: first class citizens

Slide 62

Slide 62 text

def convert(list : List[String], converter : String => Int ) = { for(e <- list) yield converter(e) } val numbers = List("1", "2") def simpleConverter(s:String) = s.toInt convert(numbers, simpleConverter) convert(numbers, (s:String) => s.toInt ) Functions: in-place

Slide 63

Slide 63 text

def convert(list : List[String], converter : String => Int ) = { for(e <- list) yield converter(e) } val numbers = List("1", "2") def simpleConverter(s:String) = s.toInt convert(numbers, simpleConverter) convert(numbers, (s:String) => s.toInt ) convert(numbers, s => s.toInt ) Functions: inferrence

Slide 64

Slide 64 text

def convert(list : List[String], converter : String => Int ) = { for(e <- list) yield converter(e) } val numbers = List("1", "2") def simpleConverter(s:String) = s.toInt convert(numbers, simpleConverter) convert(numbers, (s:String) => s.toInt ) convert(numbers, s => s.toInt ) convert(numbers, simpleConverter(_) ) convert(numbers, _.toInt ) Functions: argument placeholder

Slide 65

Slide 65 text

def simpleConverter(s:String) = s.toInt var converter : String => Int = simpleConverter var converter2 = simpleConverter _ Function variables

Slide 66

Slide 66 text

def simpleConverter(s:String) = s.toInt var converter = simpleConverter _ Unexpected function

Slide 67

Slide 67 text

var random = Math.random What is random? Double, or function? Unexpected function

Slide 68

Slide 68 text

var random = Math.random random: Double = 0.0013004673438463676 Unexpected function

Slide 69

Slide 69 text

var random = Math.random random: Double = 0.0013004673438463676 var random = Math.random _ random: () => Double = Unexpected function

Slide 70

Slide 70 text

def randomNumber(from : Int, to : Int, generator : () => Double) = { from + (generator() * (to-from) ).toInt } randomNumber(20,100, () => (System.nanoTime % 10000)/10000.0) Zero-arg function

Slide 71

Slide 71 text

def randomNumber(from:Int, to:Int, generator: () => Double) = { from + (generator() * (to-from) ).toInt } randomNumber(20,100, () => (System.nanoTime % 10000) / 10000.0 ) def randomNumber(from:Int, to:Int, generator: => Double) = { from + (generator() * (to-from) ).toInt } randomNumber(20,100, (System.nanoTime % 10000) / 10000.0 ) Closure, or param-by- name

Slide 72

Slide 72 text

var assertsEnabled = false def assert(ex : => Boolean) = { if (assertsEnabled && !ex) throw new Exception("Assertion failed!") } assert(1 > 8) Lazy param-by-name

Slide 73

Slide 73 text

def add1(a:Int, b:Int) = a+b def add2(a:Int)(b:Int) = a+b add2(1)(2) == add1(1,2) Currying

Slide 74

Slide 74 text

println("2") -> 2 println{"2"} -> 2 println{ val a = 1 (a+a).toString } -> 2 {} instead of ()

Slide 75

Slide 75 text

def retry[T](attempts:Int)(block: => T) : T = { try{ block }catch{ case x => if (attempts == 1) throw x retry(attempts - 1)(block) } } var content = retry(3){ Source.fromFile("someFile.txt").toString } println(content) New control structures

Slide 76

Slide 76 text

def printAll(words : String*){ words foreach println } printAll("1", "2") printAll("1", "2", "3") printAll(Array("1","2"):_*) Varargs

Slide 77

Slide 77 text

Scala for Java Developers It is simpler than you think Peter Gabryanczyk @piotrga [email protected] http://blog.scala4java.com