Top Banner
Intro to Scala for Java Devs Sungard– 4/17/2012
46

Scala for Java Programmers

May 10, 2015

Download

Technology

Eric Pederson

Introduction to Scala for Java developers
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Scala for Java Programmers

Intro to Scala for Java Devs

Sungard– 4/17/2012

Page 2: Scala for Java Programmers

Intro

•  Eric Pederson –  [email protected] – Twitter @ericacm –  Sourcedelica.com/blog – Background in Java, Groovy, Javascript, PHP, etc.

•  Using Scala for last two years •  Two Scala apps developed for NYSE in

Production

Page 3: Scala for Java Programmers

Platform at NYSE

•  Scala 2.9.1 •  JDK 1.6 •  Tomcat / JBoss •  Maven •  Using lots of Java libraries

– Spring, Hibernate, CXF, Mule, ApacheMQ – Bouncycastle, OpenSAML, Velocity, etc, etc.

Page 4: Scala for Java Programmers

What is Scala?

•  Hybrid Object-Functional language •  Statically typed •  Developed by Martin Odersky

– Java Generics – Java Compiler (1.3+)

•  First release in 2003

Page 5: Scala for Java Programmers

What is Scala?

•  Designed for general purpose programming

•  Performance on par with Java* •  Scalable

– Designed to write programs ranging from scripts up to huge systems

– You don’t have to use all of the features to be productive

*  There  are  some  gotchas  you  have  to  watch  out  for  

Page 6: Scala for Java Programmers

Why Should I Use Scala?

•  Allows you to write very concise code – Productivity on the level of Groovy / Ruby

•  Concurrency-ready •  Excellent interoperability with Java code •  Lots of other reasons…

Page 7: Scala for Java Programmers

Conciseness

•  Code size reduced by 2-3x compared to Java

•  Less code == easier to read •  Less code == fewer bugs

Page 8: Scala for Java Programmers

Conciseness

•  Type Inference •  Expressions, not statements •  Higher-ordered functions •  Case classes •  Pattern matching

Page 9: Scala for Java Programmers

Type Inference

•  Variables

•  Method return types

•  Generic type parameters

val  subscrip7onEvents  =  foo()    

def  listOfPeople  =  List(“Paul”,  “Eric”,  “John”,  “Mar7n”)    

case  class  MyPair[A,  B](x:  A,  y:  B)  val  p  =  MyPair(1,  “foo”)          //  p  is  MyPair[Int,  String]  

Page 10: Scala for Java Programmers

Type inference

•  Java

•  Scala

HashMap<String,  Customer>  customers  =                  new  HashMap<String,  Customer>();  customers.add("id1",    

   new  Customer("Eric",  "917-­‐444-­‐1234");  customers.add("id2",    

   new  Customer("Paul",  "718-­‐666-­‐9876");  

val  customers  =  HashMap(                      "id1"-­‐>Customer("Eric",  "917-­‐434-­‐1852"),                        "id2"-­‐>Customer("Paul",  "718-­‐666-­‐9876"))    

Page 11: Scala for Java Programmers

Expressions, not statements

val  server  =  if  (environment  ==  "development”)  {              val  factory  =  new  MBeanServerFactoryBean              factory.aberProper7esSet()              factory.getObject.asInstanceOf[MbeanServer]  }  else  {              val  clazz  =                            Class.forName("org.jboss.mx.u7l.MBeanServerLocator")              clazz.getMethod("locateJBoss”).invoke(null)  }    //  server is assigned one of the bold values  

Page 12: Scala for Java Programmers

Expressions, not statements

val  n  =  try  {          userInput.toInt  }  catch  {          case  _  =>  0  }    //  n  is  an  Int,  0  if  unable  to  parse  userInput  

Page 13: Scala for Java Programmers

Collections API

•  Very comprehensive – For example, over 200 methods on List  

•  Higher ordered functions –  foreach,  map,  flatMap,  exists,  forall,  find,  findAll,  filter,  groupBy,  par77on, etc.

•  Concise literals •  Immutable and mutable variations

Page 14: Scala for Java Programmers

Collection Literals

•  val  l1  =  List(1,  2,  3)  

•  val  m1  =  Map(“name”  -­‐>  “Eric”,  “city”  -­‐>  “NYC”)  

•  val  s1  =  Set(Car(“Ford”),  Car(“Isuzu”),  Car(“VW”))  

Page 15: Scala for Java Programmers

Collections API

•  Scala

•  Java

val  groups  =      subscrip7onEvents.groupBy(e  =>  e.subscrip7on.id)  

 

Map<String,  List<SubscripLonEvent>>  groups  =            new  HashMap<String,  ArrayList<Subscrip7onEvent>();  for  (Subscrip7onEvent  se  :  subscrip7onEvents)  {          ArrayList<Subscrip7onEvent>  seList  =  groups.get(se.subscrip7on.id)          if  (seList  ==  null)  {                  seList  =  new  ArrayList<Subscrip7onEvent>();                  groups.put(se.subscrip7on.id,  seList)          }          seList.add(se);  }          

Page 16: Scala for Java Programmers

Count characters in documents

Try #1 – Java-esque Scala

       var  total  =  0          for  (doc  <-­‐  docs)  {              total  +=  doc.length          }  

Try #2 – Use higher order functions        var  total  =  0          docs.foreach(doc  =>  total  +=  doc.length)  

Page 17: Scala for Java Programmers

Count characters in documents Try #3 – Use fold        docs.foldLeb(0)((accum,  current)  =>  accum  +  current.length)  

Try #4 – Use type-classes (eg. Numeric)        docs.map(_.length).sum  

Try #5 – Use the 'view' method to turn multiple passes into one

       docs.view.map(_.length).sum  

Page 18: Scala for Java Programmers

Variables scala>  var  i  =  0  i:  Int  =  0    scala>  i  =  2  i:  Int  =  2    scala>  val  j  =  0  j:  Int  =  0    scala>  j  =  3  <console>:8:  error:  reassignment  to  val    scala>  lazy  val  l  =  expensiveComputa7on()  l:  Double  =  <lazy>    

Page 19: Scala for Java Programmers

Uniform Access Principle scala>  object  Ints  {            |                  var  i  =  1            |                  val  j  =  2            |                  def  k  =  i  +  j            |  }    scala>  Ints.i  res8:  Int  =  1    scala>  Ints.j  res9:  Int  =  2    scala>  Ints.k  res10:  Int  =  3    

Page 20: Scala for Java Programmers

Uniform Access Principle scala>  object  M  {            |                    private  var  pm  =  0            |                    def  m  =  pm            |                    def  m_=(in:  Int)  {  pm  =  in  }            |  }  scala>  import  M._    scala>  m  res5:  Int  =  0    scala>  m  =  5  m:  Int  =  5    

Page 21: Scala for Java Programmers

Case Classes

•  Scala

scala>  case  class  Car(make:  String,  model:  String,  mpg:  Int)  defined  class  Car    scala>  val  c  =  Car("Honda",  "Civic",  40)  c:  Car  =  Car(Honda,Civic,40)  

     

Page 22: Scala for Java Programmers

Case Classes

•  Java public  class  Car  implements  scala.Product,  scala.Serializable    {          final  private  String  make,  model;          final  private  int  mpg;          Car(String  make,  String  model,  int  mpg)  {                  this.make  =  make;    this.model  =  model;  this.mpg  =  mpg;          }          public  String  getMake()  {  return  make;  }          public  String  getModel()  {  return  model;  }          public  int  getMpg()  {  return  mpg;  }          public  String  toString()  {  return  “Car(  “  +  make  +  ….  }          public  boolean  equals(Object  that)  {  if  (that  instanceOf  Car)  &&  ……  }          public  int  hashCode()  {  return  19  +  ……  }          public  Car  copy(String  make,  String  model,  int  mpg)  {  …..  }          //  plus  9  other  Scala-­‐specific  methods  }      

Page 23: Scala for Java Programmers

Case Classes

•  Case classes can also have mutable fields and methods

•  In Scala you can define multiple classes per source file

case  class  Car(make:  String,  model:  String,  mpg:  Int,  var  odometer)  {          def  driveMiles(miles:  Int)  {  odometer  +=  miles  }  }      

Page 24: Scala for Java Programmers

Pattern Matching

•  Case Classes

// Class hierarchy: trait Expr case class Num(value : int) extends Expr case class Var(name : String) extends Expr case class Mul(left : Expr, right : Expr) extends Expr // Simplification rule: e match { case Mul(x, Num(1)) ⇒ x case _ ⇒ e }

Page 25: Scala for Java Programmers

Pattern Matching

•  Match on constants

 def  describe(x:  Any)  =  x  match  {          case  5  =>  "five"          case  true  =>  "truth"          case  "hello"  =>  "hi!”        case  Nil  =>  "the  empty  list"          case  _  =>  "something  else”    }  

Page 26: Scala for Java Programmers

Pattern Matching

•  Typed patterns

def  generalSize(x:  Any)  =  x  match  {        case  s:  String  =>  s.length          case  m:  Map[_,  _]  =>  m.size          case  _  =>  -­‐1    }  

Page 27: Scala for Java Programmers

No Checked Exceptions

//  Look  ma,  no  throws  clause!  def  foo()  {          throw  new  java.lang.Excep7on  }  

Page 28: Scala for Java Programmers

Concurrency-readiness

•  The future present is many cores •  Writing thread-safe code in Java is very

difficult – Mostly due to shared, mutable state

Page 29: Scala for Java Programmers

Concurrency-readiness

•  Scala – Excellent support for immutability – Actors / Futures – Parallel collections

Page 30: Scala for Java Programmers

Immutability

•  Case classes •  Immutable collections are default

– Copies of collections share data

•  val vs. var, val is encouraged •  Method parameters are vals

Page 31: Scala for Java Programmers

Actors

•  Included in standard Scala library •  Simplified multithreading and

coordination •  Based on message passing

– Each actor has a mailbox queue of messages

•  Implementation based on Erlang

Page 32: Scala for Java Programmers

Actors        

object  Coun7ngActor  extends  Actor  {            def  act()  {                    for  (i  <-­‐  1  to  10)  {                            println("Number:  "+i)                          Thread.sleep(1000)                    }            }    }      Coun7ngActor.start()  

Page 33: Scala for Java Programmers

Actors

import  scala.actors.Actor._      val  echoActor  =  actor  {          while  (true)  {                  receive  {                          case  msg  =>  println("received:  ”  +  msg)                  }          }  }  echoActor  !  "hello"    echoActor  !  "world!"    

Page 34: Scala for Java Programmers

Futures  Return a Future immediately, run func in new thread  scala>  future  {  Thread.sleep(10000);  println("hi");  10  }  res2:  scala.actors.Future[Int]  =  <  func7on0>        Use the Future apply()  method to get the result  scala>  res2()          //  blocks  wai7ng  for  sleep()  to  finish  hi  res3:  Int  =  10  

Page 35: Scala for Java Programmers

Actors / Futures / STM

•  Akka provides more robust Actors and Futures

•  Also provides – Distributed (Remote) Actors – Software Transactional Memory – Java API

Page 36: Scala for Java Programmers

Parallel Collections

•  Add .par to collection to get parallel version

•  Uses JDK7 fork-join framework •  Example:

– Filter is run in parallel, results are collected, then map is run in parallel

myData.par.filter(_.expensiveTest()).map(_.expensiveComputa7on())  

Page 37: Scala for Java Programmers

Interoperability with Java

•  Scala classes are Java classes •  You can pass Scala objects to Java

methods and vice-versa •  For the most part, seamless interop

– Cannot use Scala-only features from Java

Page 38: Scala for Java Programmers

Java Interop Example @En7ty  class  Subscrip7onEvent  {          @Id  @GeneratedValue          var  id:  Long  =  _            @ManyToOne(op7onal=false)          var  subscrip7on:  Subscrip7on  =  _            var  address:  String  =  _            @Index(name="Subscrip7onEventStatus")          private  var  status:  String  =  _          def  deliveryStatus  =  DeliveryStatus.withName(status)          def  deliveryStatus_=(s:  DeliveryStatus)  {  status  =  s.toString  }  }  

Page 39: Scala for Java Programmers

Java Interop Example @Controller  @RequestMapping(Array("/report"))  class  ReportController  {        class  MessageDto(message:  Message)  {          @BeanProperty  val  id  =  message.id          @BeanProperty  val  address  =  message.address          //  …      }                  @RequestMapping(Array("/messages"))      def  messages(@RequestParam(value="fromDate”)  from:  String,                                                              map:  ExtendedModelMap):  String  =  {                    //…                map.put(“messages”,  asJavaCollec7on(messageDtos))                  “report/messages”              }    

Page 40: Scala for Java Programmers

JavaConversions

•  Add Scala collection API methods to Java collections

 import  collec7on.JavaConversions._            import  collec7on.Iterable            import  java.u7l.{List=>JList}      def  goodStudents(students:  JList[Student]):  Iterable[String]  =              students.filter(_.score  >  5).map(_.name)  

   

Page 41: Scala for Java Programmers

Named and Default Params

•  Named parameters

•  Default parameters

def  resize(width:  Int,  height:  Int)  =  {  ...  }  resize(width  =  120,  height  =  42)  

def  f(elems:  List[Int],  x:  Int  =  0,  cond:  Boolean  =  true)  f(List(1))  f(Nil,  cond  =  false)  

Page 42: Scala for Java Programmers

By-name Parameters

•  Method parameters can be lazily evaluated

class  Logger  {          def  debug(msg:  =>  String)  {  

         if  (isDebug)  doLog(DEBUG,  msg)          }  }    log.debug(“this  “  +  “  is  “  +  “expensive”)  

 

Page 43: Scala for Java Programmers

Type Conveniences

•  Type Aliases type  MyMap  =            mutable.HashMap[String,  mutable.HashMap[String,  Int]]  

 •  Import Aliases            import  com.nyx.domain.no7fica7on.{Topic=>DomainTopic}    

Page 44: Scala for Java Programmers

Mixins

•  Multiple implementation inheritance  trait  UserIden7fierCmd  extends  ApiKeyCmd  {            var  userId:  String  =  _          def  getUser  =  {…}  }    trait  RoleIdCmd  extends  ApiKeyCmd  {  var…    def…  }    object  cmd  extends  UserIden7fierCmd  with  RoleIdCmd  {..}  

Page 45: Scala for Java Programmers

Duck Typing

type  Closeable  =  {  def  close():  Unit  }    def  using[T  <:  Closeable,  S]  (obj:  T)(func:  T  =>  S):  S  =  {            val  result  =  func  (obj)            obj.close()            result  }    val  fis  =  new  FileInputStream(“data.txt”)    using(fis)  {  f  =>          while  (f.read()  !=  -­‐1)  {}  }    

Page 46: Scala for Java Programmers

More Information

•  My Scala Links gist – https://gist.github.com/1249298