现在的位置: 首页 > 综合 > 正文

scala学习三 控制结构

2019年05月27日 ⁄ 综合 ⁄ 共 6401字 ⁄ 字号 评论关闭

本篇采用比较的方式展示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>


Java版本的三元操作符:

<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>


Java版本的while语句(以快速排序为例):

<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>


for控制结构:

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 表达式的核心。ListArray,甚至是您自己的自定义类型,都可以在 for 中使用。(在scala的源码中你会发现,RichInt这个类中的to方法,然后一路跟踪你会发现一个抽象基类实现了Iterable接口)
for的特殊性:

(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(".")
  }
}

match控制结构(不仅仅是对string的匹配,还可以进行构造参数的匹配等,下次再作补充):

// 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?")
      }
  }
}


抱歉!评论已关闭.