Scala For Java Developers
HOME > [NFJS 2015](NFJS 2015) > [Scala For Java Developers](Scala For Java Developers)
Daniel Hinojosa (@dhinojosa)
###Positives of Scala
- Type Inferencing
- It's like Java++
- Default: things are Immutable
- Concurrency APIs
###Negatives of Scala
- They don't really care about backwards compatability
- their artifact id in maven central have versions in them...
- Difficult language to learn
Scala can run in an intrepreted mode. You don't need a main method when running in intrepreted mode.
Scala, we prefer Immutability, so your primary constructor should take everything. Unlike Java where you create an object and then set a bunch of things.
The filename doesn't have to equal the Class name in scala. You can have multiple classes in the same file
REPL - Read Evaluate Print Loop
just type scala
:reset
- clear everything
:paste
- so you can paste a bunch of code, then hit control-D
:help
:quit
You also have up arrow and code completion ("Hello". will show you all the methods on String)
Use it with Java
val alist = new java.util.ArrayList[java.lang.Integer])_
You can put object
, class
or traits
in compliable scala files.
http://scala-ide.org You can use Scala Worksheets which are like iOS Playgrounds (live coding)
http://hub.darcs.net/psnively/spring-scala
##val vs var val makes an immutable reference var make a mutable reference
val c:Int = 4
val d:Short = 50
val e = 70:Short
:load Employee.scala
class Employee(firstName:String, lastName:String)
val e = new Employee("Bob","Jones")
e has no access to firstName/lastName
Add val to the property and it creates a final member variable for it
class Employee(val firstName:String, lastName:String)
val e = new Employee("Bob","Jones")
println("Fristname: " + e.firstName)
If you use var
, it will provide you with a mechanism to change that field):
class Employee(val firstName:String, var lastName:String)
val e = new Employee("Bob","Jones")
println("Fristname: " + e.firstName)
println("lastname: " + e.lastName)
e.lastName = "Saggit"
Again, they don't like var
scala> val howMuchCanIMake_? = 5000
howMuchCanIMake_?: Int = 5000
scala> val `Hi there` = 10
Hi there: Int = 10
scala> val `true` = false
true: Boolean = false
scala> val `return` = 20
return: Int = 20
scala> val `void` = 200
void: Int = 200
scala> if (`true`) `return` else `void`
res0: Int = 200
All the same primitives are there and they mean the same (byte is 8 bits, etc).
Operator Overloading:
val b = 13 + 20
val c = 13.+(20)
val result = if (x > 30) 12 else 14
You hardly use while/do while loops because you have to use a var
with them
for ( i <- (1 to 10)) println(i))
for comphrensions:
var r = for (i <- (1 to 10)) yield (i + 2)
String interplation:
var x = "Lionel Ritchie"
var r = s"Hello $x"
var r = s"Hello ${x.size}"
String formatting:
var r = "Hello %s".format(x)
scala.Any is the root of Everything. No more java.lang.Object
Null is the subtype of Any Reference
Nothing is the subtype of Any. Nothing is abstract and final. (Ha)
def foo(x:Int, y:Int):Int = {
return x + y
}
THe last evaluated statement is always returned. So you don't need the return:
def foo(x:Int, y:Int):Int = {
x + y
}
You also don't need the curly braces:
def foo(x:Int, y:Int):Int = x + y
You must have the =
if you are returning something from your method. This is wrong:
def foo(x:Int, y:Int):Int {
x + y
}
This will set the return type to Unit
which is basically void
val u = ()
will return a Unit
A Unit
is often referred to as a Pure Side Effect
Setters are a Unit
(changing state). Printing to the screen, IO, etc could all be considered Pure Side Effects.
@BeanProperty
will make them generate
override def toString = s"Employee($firstName, $lastName)"
x.isInstanceOf([Employee])
or x.asInstanceOf([Employee])
==
is back. Same as .equals()
if you want to test object ref equality you use eq
a eq b
Just put case
in front of your class and you will get a toString
, equals
, and hashcode
implementations.
case class Employee (blah)...
You also don't need the new
keyword when you create them...
A method named apply
is like a default method and you can call it without calling it by name:
scala> class Foo(x:Int) {
| def bar(y:Int) = x + y
| }
defined class Foo
scala> var a = new Foo(10)
a: Foo = Foo@10895b16
scala> a.bar(30)
res0: Int = 40
scala> class Foo(x:Int) {
| def apply(y:Int) = x + y
| }
defined class Foo
scala> var a = new Foo(10)
a: Foo = Foo@41b1f51e
scala> a.apply(30)
res2: Int = 40
scala> a(30)
res3: Int = 40
###In fix operator
scala> case class Foo(x:Int) {
| def +(y:Int) = new Foo(x + y)
| }
defined class Foo
scala> val a = Foo(25)
a: Foo = Foo(25)
scala> a.+(40)
res5: Foo = Foo(65)
scala> a + 30
res6: Foo = Foo(55)
scala> Foo(30) + 100
res7: Foo = Foo(130)
###Right associativity:
If a method ends in :
then it is right associativity.
scala> case class Foo(x:Int) {
| def ~:(y:Int) = new Foo(x + y)
| }
defined class Foo
scala> Foo(10).~:(30)
res8: Foo = Foo(40)
scala> 30 ~: Foo(40)
res9: Foo = Foo(70)
This is how lists are created
scala> 1 :: 2 :: 3 :: 4 :: Nil
res10: List[Int] = List(1, 2, 3, 4)
It takes Nil
(which is an empty list) adds 4, adds 3, adds 2, adds 1.
##Options
Some
or None
are subclasses of Option
Same as the Java 8 Optional
You use it with getOrElse
##Object Singleton:
scala> object MySingleton
defined object MySingleton
scala> var a = MySingleton
a: MySingleton.type = MySingleton$@697d6ded
scala> var b = MySingleton
b: MySingleton.type = MySingleton$@697d6ded
scala> a == b
res11: Boolean = true
scala> a eq b
res12: Boolean = true
scala> object MySingleton {
| var x = 10
| def foo(y:Int) = {
| x = x + y
| x
| }
| }
defined object MySingleton
scala> MySingleton.foo(19)
res13: Int = 29
Object with the same name as a the class and inside the same file.
The object can see the private info inside the class and vice verse
scala> :paste
// Entering paste mode (ctrl-D to finish)
class Employee(val firstName:String, var lastName:String, private val ssn:String)
object Employee {
def identityTheft(e:Employee) = e.ssn
}
// Exiting paste mode, now interpreting.
defined class Employee
defined object Employee
scala> val e1 = new Employee("Clark","Kent","123-456-1234")
e1: Employee = Employee@34045582
scala> e1.ssn
<console>:14: error: value ssn is not a member of Employee
e1.ssn
^
scala> Employee.identityTheft(e1)
res17: String = 123-456-1234
Add a factory, but do it awesomly with apply
:
case class Employee(val firstName:String, var lastName:String, private val ssn:String)
object Employee {
def apply(firstName:String, lastName:String) = new Employee(firstName, lastName, "000-000-0000")
def identityTheft(e:Employee) = e.ssn
}
##Tuples Java 8 doesn't have Tuples
scala> (1, "Wow")
res22: (Int, String) = (1,Wow)
Same as
val t:Tuple2[Int, String] = Tuple2.apply(1, "Wow")
scala> t._1
res23: Int = 1
scala> t._2
res24: String = Wow
scala> t.swap
res25: (String, Int) = (Wow,1)
Ever want to return more than one return value? just return a Tuple.
##Collections
scala> List(1,2,3,4)
res20: List[Int] = List(1, 2, 3, 4)
###Map
cala> var m = Map((1,"One"),(2,"Two"))
m: scala.collection.immutable.Map[Int,String] = Map(1 -> One, 2 -> Two)
scala> var m2 = Map(1 -> "one", 2 -> "two")
m2: scala.collection.immutable.Map[Int,String] = Map(1 -> one, 2 -> two)
Getting values
scala> m.get(1)
res26: Option[String] = Some(One)
scala> m.get(5)
res27: Option[String] = None
scala> m(1)
res28: String = One
scala> m(6)
java.util.NoSuchElementException: key not found: 6
at scala.collection.MapLike$class.default(MapLike.scala:228)
at scala.collection.AbstractMap.default(Map.scala:59)
at scala.collection.MapLike$class.apply(MapLike.scala:141)
at scala.collection.AbstractMap.apply(Map.scala:59)
... 33 elided
###Sets
Set(1,2,3,4,5)
scala> "Hello, how is it going".apply(4)
res30: Char = o
trait
is like an Interface
scala> val f:Function1[String, Int] = new Function1[String, Int]() {
| def apply(s:String) = s.size
| }
f: String => Int = <function1>
scala> f.apply("Captain Crunch")
res31: Int = 14
Short Hand:
scala> val f = (s:String) => s.size
f: String => Int = <function1>
scala> f("Captain Crunch")
res32: Int = 14
scala> List("colorado","new mexico","arizona").map(f)
res33: List[Int] = List(8, 10, 7)
scala> List(1,2,3,4).map(x => x + 10)
res34: List[Int] = List(11, 12, 13, 14)
scala> List(1,2,3,4).map(_ + 10)
res35: List[Int] = List(11, 12, 13, 14)
_
is the same as it
in groovy.
foreach
returns a Unit
scala> List(1,2,3,4).foreach(x => println(x))
1
2
3
4
scala> List(1,2,3,4).foreach(println(_))
1
2
3
4
scala> List(1,2,3,4) foreach println
1
2
3
4
###filter
scala> "Hellllooooo Elaine".filter(x => Set('a','e','i','o','u').contains(x))
res40: String = eoooooaie
scala> class Foo(x:Int) {
| def bar(y:Int) = x + y
| }
defined class Foo
scala> new Foo(10)
res41: Foo = Foo@4926f6d6
scala> var z = res41.bar _
z: Int => Int = <function1>
scala> val foo = new Foo(10);
foo: Foo = Foo@69f4fa56
scala> (1 to 10).map(x => foo.bar(x))
res42: scala.collection.immutable.IndexedSeq[Int] = Vector(11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
scala> (1 to 10).map(foo.bar _)
res43: scala.collection.immutable.IndexedSeq[Int] = Vector(11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
scala> (1 to 10).map(foo.bar)
res44: scala.collection.immutable.IndexedSeq[Int] = Vector(11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
scala> (1 to 10) map foo.bar
res45: scala.collection.immutable.IndexedSeq[Int] = Vector(11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
We want to take a list of groceries and turn them into a shopping list.
scala> var groceries = List("Eggs", "Milk", "Pepperoni", "Naan", "Broccoli")
groceries: List[String] = List(Eggs, Milk, Pepperoni, Naan, Broccoli)
scala> groceries.zipWithIndex.map(x => x.swap).map(t => (t._1 +1, t._2)).map(t => s"${t._1}. ${t._2}").mkString("\n")
res52: String =
1. Eggs
2. Milk
3. Pepperoni
4. Naan
5. Broccoli
##Parallelization
scala> (1 to 10000).par.map{x => println(Thread.currentThread.getName()); x + 3}
ACES Learn to Code
- Git, GitHub GH-Pages
- Ozone Platform Developer Setup
- HTML, JavaScript, CSS
- Tomcat Web Server Setup
- A Simple Node.js App
- Spark with Docker
- Best Practices for Software Development
Other Tutorials
Conferences
- 2018 - DevOps Days Baltimore
- 2018 DevOps Days Baltimore, Part 2
- DevOpsDays---Baltimore
- Cross-Domain-Technical-Forum
- 2017 Potential Conferences
- LAS December 5th 2016
- DI2E Plugfest 2016
- OSCON 2015
- RWX-2015
- SpringOne-2017
- OSCON-2018
- DinosaurJS 2018
Training
- Developing on AWS
- Agile Team Facilitation
- Amazon AWS Big Data Solutions Day
- Cloudera Developer Training for Spark and Hadoop May 2016