Created by Josef Vlach / vlach.josef@gmail.com
object MyApp { def main(args: Array[String]): Unit = { println("Hello World!") } } object MyApp extends App { println("Hello World!") }
val msg = "Hello, world!" msg = "Goodbye cruel world!" // error: reassignment to val var greeting = "Hello, world!" greeting = "Leave me alone, world!" // OK val msg2: java.lang.String = "Hello again, world!" val msg3: String = "Hello again, world!"
def getFullName(firstName: String, lastName: String): String = { firstName + " " + lastName }
def getFullName(firstName: String, lastName: String): String = { val result: StringBuilder = new StringBuilder if(!firstName.trim.isEmpty) { result append firstName } if(!lastName.trim.isEmpty) { if(!result.isEmpty) { result append " " } result append lastName } result.toString }
1 + 2 (1).+(2) result.append(a).append(b).append(c) result append a append b append c
def getFullName(firstName: String, lastName: String): String = { val result: StringBuilder = new StringBuilder if(!firstName.trim.isEmpty) { result append firstName } if(!lastName.trim.isEmpty) { if(!result.isEmpty) { result append " " } result append lastName } result.toString }
def getFullName(firstName: String, lastName: String) = List(firstName, lastName) filterNot (_.trim.isEmpty) mkString " "
val color = if(user.isBlocked) "red" else "green" val number = try "123".toInt catch { case e: NumberFormatException => 0 }
def getUser( firstName: String = "John", lastName: String = "Doe", age: Int = -1) = { // ... }
createUser(user, true, false, false, true, false, false)
createUser( user = user, encryptPassword = true, admin = false, ldapAuth = false, suspicious = true, blocked = false, visible = false)
public class User { private String firstName; private String lastName; private int age; public User(String firstName, String lastName, int age) { this.firstName = firstName; this.lastName = lastName; this.age = age; } public User(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public User() {}
public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName;} public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result; + ((firstName == null) ? 0 : firstName.hashCode()); result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); return result; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User other = (User) o; return age == other.age && firstName.equals(other.firstName) && lastName.equals(other.lastName); }
@Override public String toString() { return "User(" + firstName + ", " + lastName + ", " + age + ")"; } }
case class User(var firstName: String, var lastName: String, var age: Int)
val greeting: Option[String] = Some("Hello world")
val greeting: Option[String] = None
case class User( id: Int, firstName: String, lastName: String, age: Int, gender: Option[String]) object UserRepository { private val users = Map( 1 -> User(1, "John", "Doe", 32, Some("male")), 2 -> User(2, "Johanna", "Doe", 30, None)) def findById(id: Int): Option[User] = users.get(id) def findAll = users.values }
val user1 = UserRepository.findById(1) if(user1.isDefined) { println(user1.get.firstName) } // will print "John"Very often, you want to work with a fallback or default value in case an optional value is absent. This use case is covered pretty well by the getOrElse method defined on Option:
val user = User(2, "Johanna", "Doe", 30, None) println("Gender: " + user.gender.getOrElse("not specified")) // will print "Gender: not specified"Or use Pattern Matching
switch (whatIsThis) { case 8: case 10: doSomething(); break; case 12: doSomethingElse(); break; default: doDefault(); }
whatIsThis match { case 8 | 10 => something case 12 => somethingElse case _ => defaultValue }
whatIsThis match { case _ => "anything!" }
whatIsThis match { case 42 => "a magic no." case "hello!" => "a greeting" case math.Pi => "another magic no." case _ => "something else" }
whatIsThis match { case 0 => "zero" case somethingElse => "not zero: " + somethingElse }
whatIsThis match { case n: Int => "aah, a number!?" case c: Character => "it's" + c.name }
sealed abstract class Shape case class Circle( radius : Double ) extends Shape case class Rectangle( width : Double, height : Double ) extends Shape case class Triangle( base : Double, height : Double ) extends Shape
whatIsThis match { case Circle( radius ) => Pi * ( pow( radius, 2.0 ) ) case Rectangle( 1, height ) => height case Rectangle( width, 1 ) => width case Rectangle( width, height ) => width * height case Triangle( 0, _ ) | Triangle( _, 0 ) => 0 case Triangle( base, height ) => height * base / 2 }
whatIsThis match { case (a, b) => "Tuple2" case (42, math.Pi, _) => "magic numbers + anything" case (s: String, _, _) => "matched string on first position " + s case (a, b, c) => "matched " + a + b + c case _ => "no match" }
val user = User(2, "Johanna", "Doe", 30, None) val gender = user.gender match { case Some(gender) => gender case None => "not specified" } println("Gender:" + gender)
public long vypoctiDotaci(Zadost zadost, List<ZadostOblast> oblasti) { long celkovaDotace = 0; for (ZadostOblast oblast : oblasti) { long naklady = oblast.getNakladySkutecne(); long oblastDotace = naklady * getKoeficient(zadost); oblast.setDotace(oblastDotace); celkovaDotace += oblastDotace; } return celkovaDotace; }
( x: Int, y: Int ) => x + y ( a: Int, b: Int, c: Int ) => { val aSquare = a * a val bSquare = b * b val cSquare = c * c aSquare + bSquare == cSquare }
val add = ( x: Int, y: Int ) => x + y val isPythagoras = ( a: Int, b: Int, c: Int ) => { val aSquare = a * a val bSquare = b * b val cSquare = c * c aSquare + bSquare == cSquare }
val add: (Int, Int) => Int = ( x: Int, y: Int ) => x + y val isPythagoras: (Int, Int, Int) => Boolean = ( a: Int, b: Int, c: Int ) => { val aSquare = a * a val bSquare = b * b val cSquare = c * c aSquare + bSquare == cSquare }
add(3, 8) // 11 isPythagoras(1,2,3) // false isPythagoras(3,4,5) // true
public List<User> findUserByFirstName(List<User> users, String firstName) { List<User> foundUsers = new ArrayList<User>(); for(User user: users) { if(user.getFirstName().contains(firstName)) { foundUsers.add(user); } } return foundUsers; } public List<User> findUserByLastName(List<User> users, String lastName) { List<User> foundUsers = new ArrayList<User>(); for(User user: users) { if(user.getLastName().contains(lastName)) { foundUsers.add(user); } } return foundUsers; }
users.filter((user: User) => user.firstName.contains("o")) users.filter((user: User) => user.lastName.contains("Mar")) users.filter(user => user.firstName.contains("o")) users.filter(user => user.lastName.contains("Mar")) users.filter(_.firstName.contains("o")) users.filter(_.lastName.contains("Mar"))
def addA(x: Int, y: Int): Int = x + y def addB(x: Int): Int => Int = y => x + y val a = addA(10, 20) val b = addB(10)(20)
def addA(x: Int, y: Int, z: Int): Int = x + y + z def addB(x: Int): Int => (Int => Int) = y => (z => x + y + z) val a = addA(1, 2, 3) val b = addB(1)(2)(3)
A pure function of type (A => B) is safe to use wherever an A is given and a B is expected.
It can be tested by simply giving it an A and inspecting the B.
It's always safe to call from multiple threads and order never matters.
f : (A => B)
g : (B => C)
g compose f : (A => C)
object DeathToStrategy extends App { def add(a: Int, b: Int) = a + b def subtract(a: Int, b: Int) = a - b def multiply(a: Int, b: Int) = a * b def execute(callback:(Int, Int) => Int, x: Int, y: Int) = callback(x, y) println("Add: " + execute(add, 3, 4)) println("Subtract: " + execute(subtract, 3, 4)) println("Multiply: " + execute(multiply, 3, 4)) }