Last active
July 15, 2018 16:00
Revisions
-
fuyufjh revised this gist
Jul 15, 2018 . 2 changed files with 60 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,33 @@ import akka.actor._ import akka.pattern.ask import scala.collection.mutable import scala.concurrent.Await import scala.concurrent.duration._ case class AddCount(word: String) case class ReportCount(word: String) class WordCountActor extends Actor { private val counter = mutable.Map[String, Int]() override def receive: Receive = { case AddCount(word) => counter.put(word, counter.getOrElse(word, 0)) case ReportCount(word) => sender ! counter.getOrElse(word, 0) } } object UseActor extends App { val system = ActorSystem("example") val counter = system.actorOf(Props[WordCountActor]) counter ! AddCount("hello") counter ! AddCount("world") val resultFuture = counter ? ReportCount("hello") println(s"Count of 'hello' is ${Await.result(resultFuture, 2.seconds)}") val terminateFuture = system.terminate() Await.ready(terminateFuture, Duration.Inf) } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -389,3 +389,30 @@ def factorial(fact: BigInt, number: Int): BigInt = { } println(factorial(1, 1000)) // Lazy value lazy val lazyValue = System.currentTimeMillis // Non-strict (lazy) view of strict collections (like `stream()` in Java) val people = List(("Mark", 32), ("Bob", 22), ("Jane", 8), ("Jill", 21), ("Nick", 50), ("Nancy", 42)) people.filter(_._2 > 17).filter(_._1.startsWith("J")).head people.view.filter(_._2 > 17).filter(_._1.startsWith("J")).head // compute lazily // Stream def generate(starting: Int = 0): Stream[Int] = starting #:: generate(starting + 1) // "#::" means concat lazily println(generate()) // got Stream(0, ?) println(generate().take(10).force) // got Stream(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) println(generate().take(10).toList) // got List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) // Parallel collections def squareSlow(input: Int): Int = { println(s"computing square for $input ...") Thread.sleep(1000) input * input } val inputs = List(1, 2, 3, 4, 5) inputs.map(squareSlow) // cost 5 secs inputs.par.map(squareSlow) // cost 1 secs // Input from console import scala.io.StdIn val symbol = StdIn.readLine() -
fuyufjh created this gist
Jul 11, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,391 @@ // For loop for (i <- 1 to 3) { print(s"$i,") // got: 1,2,3, } for (i <- 1 until 3) { print(s"$i,") // got: 1,2, } (1 to 3).foreach(i => print(s"$i,")) // Tuple and multiple return values def getPersonInfo(primaryKey: Int): (String, String, String) = { ("Venkat", "Subramanian", "venkats@agiledeveloper.com") } val (firstName, lastName, emailAddress) = getPersonInfo(123) // Variable number of arguments def max(values: Int*): Int = { values.foldLeft(values(0))(Math.max) } max(2, 5, 3, 7, 1, 6) // Default values for argument def mail(destination: String = "head office", mailClass: String = "first"): Unit = { println(s"sending to $destination by $mailClass class") } mail("Houston office", "Priority") mail("Houston office") mail() // Named argument mail(mailClass = "Priority", destination = "Houston office") // Implicit parameters class Wifi(name: String) { override def toString = name } def connectToNetwork(user: String)(implicit wifi: Wifi) { println(s"User: $user connected to WIFI $wifi") } def atOffice(): Unit = { implicit def officeNetwork: Wifi = new Wifi("office-network") connectToNetwork("Jill Coder") connectToNetwork("Jill Coder")(officeNetwork) // equivalent } atOffice() // Multiline String val str = """In his famous inaugural speech, John F. Kennedy said |"And so, my fellow Americans: ask not what your country can do |for you-ask what you can do for your country." He then proceeded |to speak to the citizens of the World...""" println(str) // String interpolation val product = "ticket" val price = 25.12 val discount = 10 println(s"On $product $discount% saves $$${price * discount / 100.00}") // s-interpolator println(f"On $product%s $discount%% saves $$${price * discount / 100.00}%2.2f") // f-interpolator // Operator overload case class Complex(real: Double, imaginary: Double) { def +(o: Complex): Complex = Complex(real + o.real, imaginary + o.imaginary) def *(o: Complex): Complex = Complex(real * o.real - imaginary * o.imaginary, real * o.imaginary + imaginary * o.real) override def toString: String = f"$real%f$imaginary%+fi" } val c1 = Complex(1, 4) val c2 = Complex(2, -3) val c3 = Complex(2, 2) println(s"$c1 + $c2 * $c3 = ${c1 + c2 * c3}") // Multiply first, then add // Equality val str1 = "hello" val str2 = new String("hello") println(str1 == str2) // Got true, equivalent to Java's str1.equals(str2) println(str1 eq str2) // Got false, equivalent to Java's str1 == str2 // A simple class class Person(val firstName: String, val lastName: String) { var position: String = _ // default initial value (null for AnyRef) println(s"Creating $toString") // this line is part of constructor def this(firstName: String, lastName: String, position: String) { // auxiliary constructor this(firstName, lastName) // must call primary constructor first this.position = position } override def toString = s"$firstName $lastName holds $position position" } val john = new Person("John", "Smith", "Analyst") val bill = new Person("Bill", "Walker") // Type alias class PoliceOfficer(val name: String) object CopApp extends App { type Cop = PoliceOfficer val topCop = new Cop("Jack") } // Class inherit (the override keyword) class Vehicle(val id: Int, val year: Int) { override def toString = s"ID: $id Year: $year" } class Car(override val id: Int, override val year: Int, var fuelLevel: Int) extends Vehicle(id, year) { override def toString = s"${super.toString} Fuel Level: $fuelLevel" } // Type Parameters (generic class) class Message[T](val content: T) { override def toString = s"message content is $content" def is(value: T) = value == content } // Companion object class Marker private (val color: String) { // private primary constructor override def toString = s"marker color $color" } object Marker { def getMarker(color: String): Marker = new Marker(color) def apply(color: String): Marker = new Marker(color) } println(Marker.getMarker("blue")) println(Marker("blue")) // equivalent to Marker.apply // Enumeration class object Currency extends Enumeration { type Currency = Value // 'Currency' is not only an object but also a class, so that you may use 'val c: Currency' val CNY, GBP, INR, JPY, USD = Value } import java.time.DayOfWeek import Currency._ val currency: Currency Currency.values.foreach(c => println(c)) // Package object /* package foo package object bar { def func() = ... } */ // Generics (Type Inference) def someOp(number: Int) = { // So result is Int because Nothing is always subclass of other classes if (number < 10) number * 2 // this branch returns Int else throw new IllegalArgumentException // this branch returns Nothing } // Option type def commentOnPractice(input: String): Option[String] = { input match { case "test" => Some("good") case "hack" => Some("bad") case _ => None } } val comment = commentOnPractice("hack") println(comment.getOrElse("Found no comment")) // Either type def compute(input: Double): Either[String, Double] = { if (input > 0) Right(math.sqrt(input)) // usually Right for normal result else Left("Error: invalid input") // ... and Left for error } def displayResult(result: Either[String, Double]): Unit = { result match { case Right(value) => println(s"result: $value") case Left(error) => println(s"error: $error") } } displayResult(compute(1.2)) // Support covariance (accept any subclass) class Pet(val name: String) { override def toString: String = name } class Cat(override val name: String) extends Pet(name) def payWithPets[T <: Pet](pets: Array[T]): Unit = { println("Playing with pets: " + pets.mkString(", ")) } val cats = Array(new Cat("Rover"), new Cat("Comet")) payWithPets(cats) // OK! // Support contravariance (accept any superclass) def copyPets[S, D >: S](fromPets: Array[S], toPets: Array[D]): Unit = { for (i <- fromPets.indices) toPets(i) = fromPets(i) } val pets = new Array[Pet](10) copyPets(cats, pets) // OK! // Support covariance/contravariance for customized collection class MyList[+T] // ... val list: MyList[Any] = new MyList[Int] // OK! // Implicit function class DateHelper(offset: Int) { def days(when: String) = { val today = java.time.LocalDate.now when match { case "ago" => today.minusDays(offset) case "from_now" => today.plusDays(offset) } } } object DateHelper { import scala.language.implicitConversions // otherwise the compiler will complain about 'implicit' keyword val ago = "ago" val from_now = "from_now" implicit def convertInt2DateHelper(offset: Int): DateHelper = new DateHelper(offset) } { import DateHelper._ println(2 days ago) } // Implicit class object DateUtil { val ago = "ago" val from_now = "from_now" implicit class DateHelper(val offset: Int) extends AnyVal { // 'extends AnyVal' eliminates the cost of newing object def days(when: String) = { val today = java.time.LocalDate.now when match { case "ago" => today.minusDays(offset) case "from_now" => today.plusDays(offset) } } } } { import DateUtil._ println(2 days ago) } // String interpolator val expr1 = "expr1" val expr2 = "expr2" val text1 = s"text1 $expr1 text2 $expr2" // Equivalent to: new StringContext("text1 ", " text2 ", "").s(expr1, expr2) // High-order function def printValue(generator: () => Int): Unit = { println(s"Generated value is ${generator()}") } printValue(() => 42) // Currying val array = Array(2, 3, 5, 1, 6, 4) def inject(arr: Array[Int], initial: Int)(operation: (Int, Int) => Int): Int = { // similar with `foldLeft` var carryOver = initial for (element <- array) carryOver = operation(carryOver, element) carryOver } val sum = inject(array, 0)((sum, elem) => sum + elem) // array.sum val max = inject(array, Integer.MIN_VALUE) { (large, elem) => Math.max(large, elem) } // array.max // Parameter routing (simplify) val largest1 = (Integer.MAX_VALUE /: array) { (carry, elem) => Math.max(carry, elem) } val largest2 = (Integer.MAX_VALUE /: array) { Math.max(_, _) } val largest3 = (Integer.MAX_VALUE /: array) { Math.max _ } // '_' represents list of arguments val largest4 = (Integer.MAX_VALUE /: array) { Math.max } // Partial function def log(date: java.util.Date, message: String): Unit = { println(s"$date --- $message") } val dateToday = new java.util.Date() val logWithData = log(dateToday, _: String) // logWithData: String => Unit logWithData("some message") // Pass code block and wrap around class Resource private { println("starting") def doSomething(): Unit = { println("do something") } private def cleanUp(): Unit = { println("ending") } } object Resource { def use(codeBlock: Resource => Unit): Unit = { val resource = new Resource try { codeBlock(resource) } finally { resource.cleanUp() } } } Resource.use(resource => { // Execute Around Method design pattern resource.doSomething() }) // Trait (class) trait Friend { val name: String // no actual value, so it's abstract def listen(): Unit = println(s"Your friend $name is listening") } class Human(val name: String) extends Friend class Man(override val name: String) extends Human(name) abstract class Animal class Dog(val name: String) extends Animal with Friend new Man("jason").listen() new Dog("husky").listen() // Mix-in trait into an instance class Cat(val name: String) extends Animal val angel = new Cat("Angel") with Friend angel.listen() // Set and Map val mySet = Set("foo", "bar") val myMap = Map("foo" -> 1, "bar" -> 2) myMap.get("foo") // got Option[Int] myMap("foo") // may throw NoSuchElementException // Methods end with some special characters will be bind to the second variable (':', '+', '-', '!', '~') class Sample { def unary_!(): Unit = println("called unary '!'") } val sample = new Sample !sample // List val listExample = List("foo", "bar") "hello" :: listExample // prepend List("hello", "world") ::: listExample // prepend // For expression for (_ <- 1 to 3) print("ho ") for (i <- 1 to 9; j <- i to 9) println(s"$i * $j = ${i * j}") // For ... yield (generator) val doubles = for (i <- 1 to 9) yield i * 2 val doubles2 = for (i <- 1 to 9; result = i * 2) yield result val doubleEvens = for (i <- 1 to 9; if i % 2 == 0) yield i * 2 val doubleEvens2 = for (i <- 1 to 9; result = i * 2; if i % 2 == 0) yield result // Pattern match: constants var input: Any input match { case "day" => println("matched day") case DayOfWeek.FRIDAY => println("matched Friday") case _ => println("not matched") } // Pattern match: lists and tuples input match { case ("hello", name) => println(s"hello $name") case (foo, bar) => println(s"tuple $foo $bar") } input match { case List("apple") => println("apple only") case List("red", "blue", _*) => println(s"colors red, blue, ...") } // Pattern match: type input match { case x: Int => print(s"got int $x") case s: String => printf(s"got string $s") case (v1: Int, v2: Int) => print(s"got pair of int $v1 $v2") } // Pattern match with defence input match { case x: Int if x > 1000 => print(s"got big int $x") case x: Int => print(s"got int $x") } // Pattern match: case classes trait Trade case class Buy(stock: String, quantity: Int) extends Trade case class Sell(stock: String, quantity: Int) extends Trade var trade: Trade trade match { case Buy(stock, quantity) => print(s"Buying $quantity units of $stock") // unapply() is called case Sell(stock, quantity) => print(s"Selling $quantity units of $stock") } // Exception handling (try-catch) try { Integer.parseInt("12.34") } catch { case e: NumberFormatException => print(s"number format error: ${e.getMessage}") case _: Throwable => print("something went wrong") } // Tail recursion (TCO) @scala.annotation.tailrec // ensure TCO def factorial(fact: BigInt, number: Int): BigInt = { if (number == 0) fact else factorial(fact * number, number - 1) } println(factorial(1, 1000))