从零开始学习Spark(五)Scala进阶

Scala进阶

在后面的文章中,会涉及到一些Scala中我们还没有接触到的语法。这篇Scala进阶会在Scala基础上更进一步,完成对Scala语言特性的整体学习。

1. 闭包

看下面这个例子,multiplier函数的输出值不仅取决于输入参数i,还与变量factor相关,而factor是声明在函数外的。

有趣的是,函数可以对这个这个factor进行修改,仿佛factor是这个函数的一个私有变量。这就是闭包。

object Test {
    def multiplier (i: Int): Int = {
        factor = factor + 1
        return i * factor
    }

    var factor: Int = 6

    def main(args: Array[String]) {
        println(multiplier(1))
        println(multiplier(1))
    }
}

输出结果:

7
8

2. 字符串

Scala字符串使用的直接是java.lang.String,因此和Java的使用方法基本一致。

用几个例子就可以说明使用方法了。

// 创建字符串
val greeting: String = "Hello World"
//  String 对象是不可变的
// 如果你需要创建一个可以修改的字符串,可以使用 String Builder 类
val buf = new StringBuilder;
buf += 'a'
buf ++= "bcdef"
println( "buf is : " + buf.toString );
// 字符串长度
var len = palindrome.length();
// 字符串连接
"菜鸟教程官网: ".concat("www.runoob.com");
"菜鸟教程官网: " + ("www.runoob.com");
// 格式化输出
var fs = printf("浮点型变量为 " +
       "%f, 整型变量为 %d, 字符串为 " +
       " %s", floatVar, intVar, stringVar)

3. 数组Array

数组是Array,Array的特点是长度固定,元素可变,可以先定义后赋值

一维数组的创建方法,有三种

var z:Array[String] = new Array[String](3)
var z = new Array[String](3)
z(0) = "Runoob"; z(1) = "Baidu"; z(2) = "Google"
var z = Array("Runoob", "Baidu", "Google")

遍历数组

for ( x <- myList ) {
  println( x )
}

合并数组

var myList3 =  concat( myList1, myList2)

用range来创建区间数组

import Array._
for (x <- range(1,10,2)) {
  println(x)
}

多维数组的定义及使用

import Array._
var myMatrix = ofDim[Int](3,3)

for (i <- 0 to 2; j <- 0 to 2) {
  myMatrix(i)(j) = j;
}

4. Collections

Scala的集合包括以下五种

列表List

Scala 列表类似于数组,它们所有元素的类型都相同,但是它们也有所不同:列表是不可变的,值一旦被定义了就不能改变。

val nums: List[Int] = List(1, 2, 3, 4)
val nums = List(1, 2, 3, 4)
// 构造列表的两个基本单位是 Nil 和 ::
// Nil 也可以表示为一个空列表。
val nums = 1 :: (2 :: (3 :: (4 :: Nil)))

集合Set

Scala Set(集合)是没有重复的对象集合,所有的元素都是唯一的。Scala 集合分为可变的和不可变的集合。默认情况下,Scala 使用的是不可变集合。可变需要引入包。

val set:Set[Int] = Set(1,2,3)
val set = Set(1,2,3)

哈希表Map

Map(映射)是一种可迭代的键值对(key/value)结构。所有的值都可以通过键来获取。Map 中的键都是唯一的。默认情况下 Scala 使用不可变 Map。可变需要引入包。

var A:Map[Char,Int] = Map()
val colors = Map("red" -> "#FF0000", "azure" -> "#F0FFFF")
// 添加元素
A += ('I' -> 1)
A += ('J' -> 5)
A += ('K' -> 10)
// 访问元素
A('I')

元组Tuple

与列表一样,元组也是不可变的,但与列表不同的是元组可以包含不同类型的元素。

val t = (1, 3.14, "Fred") 
// 注意最多到Tuple22
val t = new Tuple3(1, 3.14, "Fred")

我们可以使用 t._1 访问第一个元素, t._2 访问第二个元素

选项Option

Scala Option(选项)类型用来表示一个值是可选的(有值或无值)。

Option[T] 是一个类型为 T 的可选值的容器: 如果值存在, Option[T] 就是一个 Some[T] ,如果不存在, Option[T] 就是对象 None

val a:Option[Int] = Some(5)
val b:Option[Int] = None 

比如Map的get方法返回的就是Option对象

val myMap: Map[String, String] = Map("key1" -> "value")
val value1: Option[String] = myMap.get("key1")
val value2: Option[String] = myMap.get("key2")
 
println(value1) // Some("value1")
println(value2) // None

5. 迭代器Iterator

Scala Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法。

迭代器 it 的两个基本操作是 next 和 hasNext。调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。调用 it.hasNext() 用于检测集合中是否还有元素。

val it = Iterator("Baidu", "Google", "Runoob", "Taobao")
while (it.hasNext){
  println(it.next())
}
// 获取最值
println("最大元素是:" + ita.max )
println("最小元素是:" + itb.min )
// 获取长度
println("ita.size 的值: " + ita.size )
println("itb.length 的值: " + itb.length )

6. 类和对象

直接用一个例子体会一下就好了,语法和Java只有微小的区别

class Point(val xc: Int, val yc: Int) {
   var x: Int = xc
   var y: Int = yc
   def move(dx: Int, dy: Int) {
      x = x + dx
      y = y + dy
      println ("x 的坐标点 : " + x);
      println ("y 的坐标点 : " + y);
   }
}

class Location(xc: Int, yc: Int,
   val zc :Int) extends Point(xc, yc){
   var z: Int = zc

   def move(dx: Int, dy: Int, dz: Int) {
      x = x + dx
      y = y + dy
      z = z + dz
      println ("x 的坐标点 : " + x);
      println ("y 的坐标点 : " + y);
      println ("z 的坐标点 : " + z);
   }
}

object Test {
   def main(args: Array[String]) {
      val loc = new Location(10, 20, 15);

      // 移到一个新的位置
      loc.move(10, 10, 5);
   }
}
  • Scala重写一个非抽象方法,必须用override修饰符。例子里面的move方法参数不同,算是重载了,所以不需要override。

Scala 单例对象:Scala有个非常简便的创建单例模式对象的关键词object,可以实现类似Java下单例代码的功能,object对象不能带有参数,写法如下

object Point {
   var x: Int = 1
   var y: Int = 2
   def move(dx: Int, dy: Int) {
      x = x + dx
      y = y + dy
      println ("x 的坐标点 : " + x);
      println ("y 的坐标点 : " + y);
   }
}

object Test {
   def main(args: Array[String]) {
      println(Point.x)
      Point.move(2,3)
   }
}

Java单例模式写法

public class Singleton {
    private static Singleton instance;
    private Singleton (){}
    public static Singleton getInstance() {
     if (instance == null) {
         instance = new Singleton();
     }
     return instance;
    }
}

伴生对象,与类共享名字,可以访问类的私有属性和方法

7. 特征Trait

Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。与接口不同的是,它还可以定义属性和方法的实现。

一般情况下Scala的类只能够继承单一父类,但是如果是 Trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承。

trait Equal {
    def isEqual(x: Any): Boolean
    def isNotEqual(x: Any): Boolean = !isEqual(x)
}

当需要继承一个类,扩展多个trait时,这样写

class Location(xc: Int, override val yc: Int,
   val zc :Int) extends Point(xc, yc) with Equal

8. 模式匹配

模式匹配和C及Java中的switch有点类似,但是Scala的模式匹配更为强大,可以匹配不同数据类型。

object Test {
   def main(args: Array[String]) {
      println(matchTest("two"))
      println(matchTest("test"))
      println(matchTest(1))
      println(matchTest(6))

   }
   def matchTest(x: Any): Any = x match {
      case 1 => "one"
      case "two" => 2
      case y: Int => "scala.Int"
      case _ => "many"
   }
}

输出结果为:

2
many
one
scala.Int

补充:使用了case关键字的类定义就是就是样例类(case classes),样例类是种特殊的类,经过优化以用于模式匹配。

9. 异常处理

抛出异常

throw new IllegalArgumentException

捕获异常

import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException

object Test {
   def main(args: Array[String]) {
      try {
         val f = new FileReader("input.txt")
      } catch {
         case ex: FileNotFoundException => {
            println("Missing file exception")
         }
         case ex: IOException => {
            println("IO Exception")
         }
      } finally {
         println("Exiting finally...")
      }
   }
}

执行结果为

Missing file exception
Exiting finally...

10. 提取器

Scala 提取器是一个带有unapply方法的对象。unapply方法算是apply方法的反向操作:unapply接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。

11. 文件I/O

写文件

import java.io._

object Test {
   def main(args: Array[String]) {
      val writer = new PrintWriter(new File("test.txt" ))

      writer.write("菜鸟教程")
      writer.close()
   }
}

读取输入

object Test {
   def main(args: Array[String]) {
      print("请输入菜鸟教程官网 : " )
      val line = Console.readLine
      
      println("谢谢,你输入的是: " + line)
   }
}

读文件

import scala.io.Source

object Test {
   def main(args: Array[String]) {
      println("文件内容为:" )

      Source.fromFile("test.txt" ).foreach{ 
         print 
      }
   }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,348评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,122评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,936评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,427评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,467评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,785评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,931评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,696评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,141评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,483评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,625评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,291评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,892评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,324评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,492评论 2 348

推荐阅读更多精彩内容

  • 这篇讲义只讲scala的简单使用,目的是使各位新来的同事能够首先看懂程序,因为 scala 有的语法对于之前使用习...
    MrRobot阅读 2,906评论 0 10
  • scala学习笔记 第2章 变量和数据类型 基本数据 scala的核心数据为四种 :字面量、值、变量、类型 值使...
    485b1aca799e阅读 2,115评论 0 1
  • 愿天下所有用心教书育人的老师们,节日快乐,您辛苦了!好吧,接下来让你们看看,什么叫做别人的老师! 记得某一年的教师...
    waitine阅读 645评论 2 4
  • 感觉是久未进食,只管一路行尸走肉,最后弄得自己浑身不是,极度缺乏营养。
    子悦zy阅读 225评论 0 0