Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scala for Java Developers - It is simpler than ...

Scala for Java Developers - It is simpler than you think!

Introduction to Scala for Java developers.

Piotr Gabryanczyk

January 19, 2011
Tweet

More Decks by Piotr Gabryanczyk

Other Decks in Technology

Transcript

  1. Scala for Java Developers It is simpler than you think

    Peter Gabryanczyk @piotrga [email protected] http://blog.scala4java.com
  2. var width = args(0).toDouble Is equivalent to: var width :

    Double = args(0).toDouble Type inference
  3. package scala4java object Area{ def main(args: Array[String]){ var width =

    args(0).toDouble println("Area = " + width * width ) } } Hello World
  4. class Square{ def area(width : Double) : Double = {

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

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

    * width } def area(width : Double) : Double = { width * width } def area(width : Double) = { width * width } Classes
  7. 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
  8. public class Square{ public Double area(Double width){ return width *

    width; } } vs class Square{ def area(width:Double) = width * width } Java vs Scala
  9. 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
  10. 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
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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
  18. 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
  19. class Square(var width: Double){ def area = width * width

    } var square = new Square(10) square.width = 9999 println(square.width) -> 9999 Properties
  20. 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
  21. 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
  22. 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
  23. 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
  24. 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
  25. trait Paintable{ def area : Double // abstract method def

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

    costOfPainting(paintPrice : Double) = area * paintPrice } trait Externalizable{ def externalize(out : Writer) } Traits
  27. 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
  28. class Circle(r : Double) { def area = 3.14 *

    r * r} var tableSurface = new Circle(5) with Paintable tableSurface costOfPainting 10 -> 785 Traits
  29. var i = 0 while(i < 10){ println(i) i +=

    1 } var j = 10 do{ println(j) j += 1 }while(j<10) While
  30. scala> val squares = for (i <- 1 to 3)

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

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

    2 if( modulo2 == 0) ) yield i Temporary variables
  33. 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
  34. // Importing class HashMap import scala.collection.immutable.HashMap // Importing whole content

    of package scala.collection import scala.collection._ Imports
  35. // 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
  36. // 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
  37. // 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
  38. // 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
  39. // 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
  40. def convert(list : List[String], converter : String => Int )

    = { for(e <- list) yield converter(e) } Functions: Type
  41. 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
  42. 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
  43. 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
  44. 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
  45. def simpleConverter(s:String) = s.toInt var converter : String => Int

    = simpleConverter var converter2 = simpleConverter _ Function variables
  46. var random = Math.random random: Double = 0.0013004673438463676 var random

    = Math.random _ random: () => Double = <function0> Unexpected function
  47. def randomNumber(from : Int, to : Int, generator : ()

    => Double) = { from + (generator() * (to-from) ).toInt } randomNumber(20,100, () => (System.nanoTime % 10000)/10000.0) Zero-arg function
  48. 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
  49. var assertsEnabled = false def assert(ex : => Boolean) =

    { if (assertsEnabled && !ex) throw new Exception("Assertion failed!") } assert(1 > 8) Lazy param-by-name
  50. println("2") -> 2 println{"2"} -> 2 println{ val a =

    1 (a+a).toString } -> 2 {} instead of ()
  51. 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
  52. def printAll(words : String*){ words foreach println } printAll("1", "2")

    printAll("1", "2", "3") printAll(Array("1","2"):_*) Varargs
  53. Scala for Java Developers It is simpler than you think

    Peter Gabryanczyk @piotrga [email protected] http://blog.scala4java.com