第1章——探索Scala

Scala 是一门强大的编程语言:不需要牺牲强大的静态类型检查支持,就可以写出富有表 现力而又简洁的代码。

1.2 以少胜多

Introduction/TopStock.scala

val symbols = List("AMD", "AAPL", "AMZN", "IBM", "ORCL", "MSFT")
val year = 2017

val (topStock, topPrice) =
  symbols.map { ticker ⇒ (ticker, getYearEndClosingPrice(ticker, year)) }
    .maxBy { stockPrice ⇒ stockPrice._2 }

printf(s"Top stock of $year is $topStock closing at price $$$topPrice")
Full source at GitHub

Introduction/TopStock.scala

case class Record(year: Int, month: Int, date: Int, closePrice: BigDecimal)

def getYearEndClosingPrice(symbol: String, year: Int): BigDecimal = {
  val url = s"https://raw.githubusercontent.com/ReactivePlatform/" +
    s"Pragmatic-Scala-StaticResources/master/src/main/resources/" +
    s"stocks/daily/daily_$symbol.csv"

  val data = io.Source.fromURL(url).mkString
  val maxClosePrize = data.split("\n")
    .filter(record ⇒ record.startsWith(s"$year-12"))
    .map(record ⇒ {
      val Array(timestamp, open, high, low, close, volume) = record.split(",")
      val Array(year, month, date) = timestamp.split("-")
      Record(year.toInt, month.toInt, date.toInt, BigDecimal(close.trim))
    })
    .sortBy(_.date)(Ordering[Int].reverse)
    .take(1)
    .map(_.closePrice)
    .head
  maxClosePrize
}
Full source at GitHub

运行结果

Top stock of 2017 is AMZN closing at price $1169.4700
Full source at GitHub

Introduction/FastTopStock.scala

val (topStock, topPrice) =
  symbols.par.map { ticker ⇒ (ticker, getYearEndClosingPrice(ticker, year)) }
    .maxBy { stockPrice ⇒ stockPrice._2 }
Full source at GitHub

编译sample.scala的结果

sample.scala:2:
error: type mismatch;
 found   : String("haha")
 required: Int
i = "haha" //Error
    ^
one error found
Full source at GitHub

1.3 函数式编程

Introduction/FindMax.java

 public static int findMax(List<Integer> temperatures) {
     //Java code
  int highTemperature = Integer.MIN_VALUE;
  for(int temperature : temperatures) {
   highTemperature = Math.max(highTemperature, temperature);
  }
  return highTemperature;
}
Full source at GitHub

Introduction/FindMaxImperative.scala

def findMax(temperatures: List[Int]) = {
  var highTemperature = Integer.MIN_VALUE
  for (temperature ← temperatures) {
    highTemperature = Math.max(highTemperature, temperature)
  }
  highTemperature
}
Full source at GitHub

Introduction/FindMaxFunctional.scala

def findMax(temperatures: List[Int]) = {
  temperatures.foldLeft(Integer.MIN_VALUE) { Math.max }
}
Full source at GitHub

Introduction/ScalaDoubleValues.scala

val values = List(1, 2, 3, 4, 5)

val doubleValues = values.map(_ * 2)
Full source at GitHub