本篇采用比较的方式展示Java和scala代码 (在scala中出现的 =>符合基本可以理解为一个函数了)
Java版本的if语句:
<span style="font-size:14px;">// This is Java String filename = "default.properties"; if (options.contains("configFile")) filename = (String)options.get("configFile");</span>scalar版本的if语句:
<span style="font-size:14px;">// This is Scala val filename = if (options.contains("configFile")) options.get("configFile") else "default.properties"</span>
<span style="font-size:14px;">//This is Java final String filename = options.contains("configFile") <span style="background-color: rgb(192, 192, 192);">?</span> options.get("configFile") <span style="background-color: rgb(153, 153, 153);">: </span>"default.properties";</span>
<span style="font-size:14px;">//This is Java void sort(int[] xs) { sort(xs, 0, xs.length -1 ); } void sort(int[] xs, int l, int r) { int pivot = xs[(l+r)/2]; int a = l; int b = r; while (a <= b) while (xs[a] < pivot) { a = a + 1; } while (xs[b] > pivot) { b = b – 1; } if (a <= b) { swap(xs, a, b); a = a + 1; b = b – 1; } } if (l < b) sort(xs, l, b); if (b < r) sort(xs, a, r); } void swap(int[] arr, int i, int j) { int t = arr[i]; arr[i] = arr[j]; arr[j] = t; }</span>scala版本的while代码:
<span style="font-size:14px;">//This is Scala def sort(xs: Array[Int]) { def swap(i: Int, j: Int) { val t = xs(i); xs(i) = xs(j); xs(j) = t } def sort1(l: Int, r: Int) { val pivot = xs((l + r) / 2) var i = l; var j = r while (i <= j) { while (xs(i) < pivot) i += 1 while (xs(j) > pivot) j -= 1 if (i <= j) { swap(i, j) i += 1 j -= 1 } } if (l < j) sort1(l, j) if (j < r) sort1(i, r) } sort1(0, xs.length 1) }</span>不过上面的代码不够简介,不能体现出scala的特性,接下来做出一些改进:
<span style="font-size:14px;">//This is Scala def sort(xs: Array[Int]): Array[Int] = if (xs.length <= 1) xs else { val pivot = xs(xs.length / 2) Array.concat( //contat是scala自带的合并数组的方法 sort(xs filter (pivot >)), xs filter (pivot ==), sort(xs filter (pivot <))) }</span>
<span style="font-size:14px;">// This is Scala def While (p: => Boolean) (s: => Unit) { if (p) { s ; While(p)(s) } }</span>其实在scala自带的if实现中,也是一个函数
scala中的异常捕获:
<span style="font-size:14px;">// This is Scala val url = try { new URL(possibleURL) } catch { case ex: MalformedURLException => new URL("www.tedneward.com") }</span>
<span style="font-size:14px;">// This is Scala object Application { def generateException() { System.out.println("Generating exception..."); throw new Exception("Generated exception"); } def main(args : Array[String]) { <span style="background-color: rgb(192, 192, 192);">tryWithLogging // This is not part of the language 标注部分代码也可写成 tryWithLogging(generateException) { generateException }</span> System.out.println("Exiting main()"); } def tryWithLogging (s: => Unit) { try { s } catch { case ex: Exception => // where would you like to log this? // I choose the console window, for now ex.printStackTrace() } } }</span>
scala中的控制结构的源泉 for循环结构 在for循环中有一些概念,要理解清楚(spark做准备)
<span style="font-size:14px;">object Application { def main(args : Array[String]) { for (i <-<span style="background-color: rgb(192, 192, 192);"> 1 to 10</span>) // the left-arrow means "assignment" in Scala System.out.println("Counting " + i) } }</span>同一下代码,做对比呀:
<span style="font-size:14px;">object Application { def main(args : Array[String]) { for (i <- <span style="background-color: rgb(192, 192, 192);">1.to(10)</span>) // the left-arrow means "assignment" in Scala //for后面的 ()中的内容可以理解为发生器 创建要循环的对象 这个to方法在Int类中 System.out.println("Counting " + i) } }</span>实际上,Scala 的
for
并不了解那些成员,并且并不比其他任何对象类型做得更好。它所了解的是 scala.Iterable
,scala.Iterable 定义了在集合上进行迭代的基本行为。提供 Iterable
功能(从技术上说,它是 Scala 中的一个特征,但现在将它视为一个接口)的任何东西都可以用作for
表达式的核心。List
、Array
,甚至是您自己的自定义类型,都可以在 for
中使用。(在scala的源码中你会发现,RichInt这个类中的to方法,然后一路跟踪你会发现一个抽象基类实现了Iterable接口)(1)可以使用一个 for
循环在操作过程中过滤许多项:
<span style="font-size:14px;">// This is Scala object Application { def main(args : Array[String]) { for (i <- 1 to 10;<span style="background-color: rgb(192, 192, 192);"> i % 2 == 0</span>) 这就是一个filter(过滤器:对于给定集合,通过对其内部元素的判断返回true或者false的函数) 对于for后面的整个括号就是一个发生器,用于产生提供给for循环的iterater对象的 System.out.println("Counting " + i) } }</span>
下面给出一个通过if作为过滤器的for循环例子:
<span style="font-size:14px;">// This is Scala object App { def main(args : Array[String]) = { val filesHere = (new java.io.File(".")).listFiles for ( <span style="background-color: rgb(192, 192, 192);"> file <- filesHere; if file.isFile; if file.getName.endsWith(".scala")</span> ) System.out.println("Found " + file) } }</span>处于简化的考虑,scala中可以就爱那个for括号中的语句当作代码块处理:
<span style="font-size:14px;">// This is Scala object App { def main(args : Array[String]) = { val filesHere = (new java.io.File(".")).listFiles for { <span style="background-color: rgb(192, 192, 192);"> file <- filesHere if file.isFile if file.getName.endsWith(".scala")</span> } System.out.println("Found " + file) } }</span>for的一些额外用法:
<span style="font-size:14px;">// This is Scala object App { def main(args : Array[String]) = { // Note the array-initialization syntax; the type (Array[String]) // is inferred from the initialized elements val names = Array("Ted Neward", "Neal Ford", "Scott Davis", "Venkat Subramaniam", "David Geary") for { name <- names <span style="background-color: rgb(192, 192, 192);"> firstName = name.substring(0, name.indexOf(' ')) //<span style="color: rgb(34, 34, 34); font-family: Arial, sans-serif; line-height: 22.375px;">这被称为 “中途赋值(midstream assignment)”,其工作原理如下:定义了一个新值 </span><code style="margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: baseline; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; line-height: 1.5em;">firstName</code><span style="color: rgb(34, 34, 34); font-family: Arial, sans-serif; line-height: 22.375px;">,该值用于保存每次执行循环后的 </span><code style="margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: baseline; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; line-height: 1.5em;">substring</code><span style="color: rgb(34, 34, 34); font-family: Arial, sans-serif; line-height: 22.375px;">调用的值,以后可以在循环主体中使用此值。</span></span> } System.out.println("Found " + firstName) } }</span>在for中进行嵌套迭代(可以看出嵌套迭代执行的顺序先左后右):
// This is Scala object App { def grep(pattern : String, dir : java.io.File) = { val <span style="background-color: rgb(192, 192, 192);">filesHere</span> = dir.listFiles for ( <span style="background-color: rgb(192, 192, 192);">file <- filesHere;</span> if (file.getName.endsWith(".scala") || file.getName.endsWith(".java")); <span style="background-color: rgb(192, 192, 192);"> line <- scala.io.Source.fromFile(file).getLines;</span> if line.trim.matches(pattern) ) println(line) } def main(args : Array[String]) = { val pattern = ".*object.*" grep pattern new java.io.File(".") } }
// This is Scala object App { def main(args : Array[String]) = { for (<span style="background-color: rgb(192, 192, 192);">arg</span> <- args) //定义方式 <span style="background-color: rgb(192, 192, 192);">arg match</span> { case "Java" => println("Java is nice...") case "Scala" => println("Scala is cool...") case "Ruby" => println("Ruby is for wimps...") case _ => println("What are you, a VB programmer?") } } }