林子雨编著《Spark编程基础》教材第2章的代码

大数据学习路线图

林子雨、赖永炫、陶继平编著《Spark编程基础》(教材官网)教材中的代码,在纸质教材中的印刷效果,可能会影响读者对代码的理解,为了方便读者正确理解代码或者直接拷贝代码用于上机实验,这里提供全书配套的所有代码。
查看教材所有章节的代码

第2章 Scala语言基础

cd /usr/local/scala  #这是Scala的安装目录
./bin/scala
//代码文件为/usr/local/scala/mycode/Test.scala
println("This is the first line")
println("This is the second line")
println("This is the third line")
scala> :load  /usr/local/scala/mycode/Test.scala
Loading /usr/local/scala/mycode/Test.scala…
This is the first line
This is the second line
This is the third line
//代码文件为/usr/local/scala/mycode/HelloWorld.scala
object HelloWorld {
  def main(args: Array[String]) {
  println("Hello, world!");
 }
}
cd /usr/local/scala/mycode
scalac  HelloWorld.scala
scala -classpath . HelloWorld
java  -classpath  .:/usr/local/scala/lib/scala-library.jar  HelloWorld
scala> val c='A'
c: Char = A
scala> var c1='\u0045'
c1: Char = E
scala> c1='\''
c1: Char = '
scala> val s = "hello world"
s: String = hello world
scala> val ss = """ the first line
    | the second line
    | the third line"""
ss: String =
" the first line
the second line
the third line"
scala> val a = "Xiamen University"
a: String = Xiamen University
scala> var a = 50
a: Int = 50
scala> import io.StdIn._
import io.StdIn._
scala> var i=readInt()
54
i: Int = 54
scala> var f=readFloat
1.618
f: Float = 1.618
scala> var b=readBoolean
true
b: Boolean = true
scala> var str=readLine("please input your name:")
please input your name:Li Lei
str: String = Li Lei
scala> val i=345
i: Int = 345
scala> print("i=");print(i) //两条语句位于同一行,不能省略中间的分号
i=345
scala> println("hello ");println("world")
hello
world
scala> val i = 34
i: Int = 34
scala> val f=56.5
f: Double = 56.5
scala> printf("I am %d years old and weight %.1f Kg.","Li Lie",i,f)
I am 34 years old and weight 56.5 Kg.
scala> val i=10
i: Int = 10
scala> val f=3.5
f: Double = 3.5452
scala> val s="hello"
s: String = hello
scala> println(s"$s:i=$i,f=$f")    //s插值字符串
hello:i=10,f=3.5452
scala> println(f"$s:i=$i%-4d,f=$f%.1f")   //f插值字符串
hello:i=10  ,f=3.5
scala> import java.io.PrintWriter
scala> val outputFile = new PrintWriter("test.txt")
scala> outputFile.println("Hello World")
scala> outputFile.print("Spark is good")
scala> outputFile.close()
scala> import Java.io.PrintWriter
scala> val outputFile = new PrintWriter("test.txt")
scala> val i = 9
scala> outputFile.print("%3d --> %d\n".format(i,i*i))
scala> outputFile.println(f"$i%3d --> ${i*i}%d") //与上句等效
scala> outputFile.close()
scala> import scala.io.Source
scala> val inputFile = Source.fromFile("test.txt")
scala> for (line <- inputFile.getLines())  println(line)
scala> inputFile.close()
if (表达式) {
    语句块1
}
else {
    语句块2
}
scala> val x = 6
x: Int = 6
scala> if (x>0) {println("This is a positive number")
   | } else {
   |     println("This is not a positive number")
   | }
This is a positive number
scala> val x = 3
x: Int = 3
scala> if (x>0) {
   |     println("This is a positive number")
   | } else if (x==0) {
   |     println("This is a zero")
   | } else {
   |     println("This is a negative number")
   | }
This is a positive number
scala> val a = if (6>0) 1 else -1
a: Int = 1
while (表达式){
        循环体
}
do{
        循环体
}while (表达式)
scala> for (i <- 1 to 3) println(i)
1
2
3
scala> for (i <- Array(3,5,6)) println(i)
3
5
6
scala> for (i <- 1 to 5 if i%2==0) println(i)
2
4
for (i <- 1 to 5)
    if (i%2==0) println(i)
scala> for (i <- 1 to 5; j <- 1 to 3) println(i*j)
1
2
3
2
...
scala> val r=for (i <- Array(1,2,3,4,5) if i%2==0) yield { println(i); i}
2
4
r: Array[Int] = Array(2,4)
import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
try {
val f = new FileReader("input.txt")
    // 文件操作
} catch {
case ex: FileNotFoundException =>...    // 文件不存在时的操作
case ex: IOException =>...   // 发生I/O错误时的操作
} finally {
file.close() // 确保关闭文件
}
breakable{
...
if(...) break
...
}
//代码文件为/usr/local/scala/mycode/TestBreak.scala
import util.control.Breaks._ //导入Breaks类的所有方法
val array = Array(1,3,10,5,4)
breakable{
for(i<- array){
       if(i>5) break //跳出breakable,终止for循环,相当于Java中的break
println(i)
    }
}
// 上面的for语句将输出1,3

for(i<- array){
    breakable{
        if(i>5) break //跳出breakable,终止当次循环,相当于Java的continue     println(i)
    }
}
// 上面的for语句将输出1,3,5,4
scala> val intValueArr = new Array[Int](3)
scala> val myStrArr = Array("BigData","Hadoop","Spark")
val myMatrix = Array.ofDim[Int](3,4)
val myCube = Array.ofDim[String](3,2,4)
scala> val tuple = ("BigData",2015,45.0)
scala> val (t1,t2,t3) = tuple
t1: String = BigData
t2: Int = 2015
t3: Double = 45.0
scala> var strList=List("BigData","Hadoop","Spark")
scala> val l = List[Double](1,3.4)
l: List[Double] = List(1.0, 3.4)
scala> val x=List(1,3.4,"Spark")
x: List[Any] = List(1, 3.4, Spark) //1,3.4,“Spark”最近公共类型为Any
scala> val otherList="Apache"::strList
scala> val intList = 1::2::3::Nil
scala> val vec1=Vector(1,2)
vec1: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)
scala> val vec2 = 3 +: 4 +: vec1
vec2: scala.collection.immutable.Vector[Int] = Vector(3, 4, 1, 2)
scala> val vec3 = vec2 :+ 5
vec3: scala.collection.immutable.Vector[Int] = Vector(3, 4, 1, 2, 5)
scala> vec3(3)
res6: Int = 2
scala> import  scala.collection.mutable.ListBuffer
scala> val mutableL1 = ListBuffer(10,20,30) //初始长度为3的变长列表
mutableL1: scala.collection.mutable.ListBuffer[Int] = ListBuffer(10, 20, 30)
scala> mutableL1 += 40 //在列表尾部增加一个元素40
res22: mutableL1.type = ListBuffer(10, 20, 30, 40)
scala> val mutableL2 = mutableL1:+50 //在列表尾部增加一个元素50,并返回这个新列表,原列表保持不变
mutableL2: scala.collection.mutable.ListBuffer[Int] = ListBuffer(10, 20, 30, 40, 50)
scala> mutableL1.insert(2, 60,40) //从第2个索引位置开始,插入60和40
scala> mutableL1
res24: scala.collection.mutable.ListBuffer[Int] = ListBuffer(10, 20, 60, 40, 30, 40)
scala> mutableL1 -= 40 //在数组中删除值为40的第一个元素
res25: mutableL1.type = ListBuffer(10, 20, 60, 30, 40)
scala> var temp=mutableL1.remove(2)//移除索引为2的元素,并将其返回
temp: Int = 60
scala> mutableL1
res26: scala.collection.mutable.ListBuffer[Int] = ListBuffer(10, 20, 30, 40)
scala> val r=new Range(1,5,1)
scala> var mySet = Set("Hadoop","Spark")
scala> mySet += "Scala"
scala> import scala.collection.mutable.Set
scala> val myMutableSet = Set("Database","BigData")
scala> myMutableSet += "Cloud Computing"
scala> val university = Map("XMU" ->"Xiamen University", "THU" ->"Tsinghua University","PKU"->"Peking University")
scala> import scala.collection.mutable.Map
scala> val university2 = Map("XMU" -> "Xiamen University", "THU" -> "Tsinghua University","PKU"->"Peking University")
scala> university2("XMU") = "Ximan University"
scala> university2("FZU") = "Fuzhou University"
scala> university2 += ("TJU"->"Tianjin University")
val iter = Iterator("Hadoop","Spark","Scala")
while (iter.hasNext) {
    println(iter.next())
}
class Counter{
//这里定义类的字段和方法
}
def 方法名(参数列表):返回结果类型={方法体}
class Counter {
  var value = 0
  def increment(step:Int):Unit = { value += step}
  def current():Int = {value}
}
val myCounter = new Counter
myCounter.value = 5 //访问字段
myCounter.add(3) //调用方法
println(myCounter.current) //调用无参数方法时,可以省略方法名后的括号
//代码文件为/usr/local/scala/mycode/Top.scala
class  Top(name:String,subname:String){ //顶层类
case class Nested(name:String) //嵌套类
def show{
val c=new Nested(subname)
printf("Top %s includes a Nested %s\n",name,c.name)
}
}
val t = new Top("A","B")
t.show
//代码文件为/usr/local/scala/mycode/Counter.scala
class Counter {
    private var privateValue = 0
def value = privateValue
def value_=(newValue: Int){
        if (newValue > 0) privateValue = newValue
    }
def increment(step: Int): Unit = {value += step}
    def current():Int = {value}
}
scala> :load /usr/local/scala/mycode/Counter.scala
Loading /usr/local/scala/mycode/Counter.scala…
defined class Counter
scala> val myCounter = new Counter
myCounter: Counter = Counter@f591271
scala> myCounter.value_=(3) //为privateValue设置新的值
scala> println(myCounter.value)//访问privateValue的当前值
3
myCounter.value= 3 // 等效于myCounter.value_=(3)
//代码文件为/usr/local/scala/mycode/Counter1.scala
class Counter {
    var value = 0
    def increment(step:Int):Unit = {value += step}
    def current:Int= value
       def getValue():Int = value
}
scala> :load /usr/local/scala/mycode/Counter1.scala
Loading /usr/local/scala/mycode/Counter1.scala…
defined class Counter
scala> val c=new Counter
c: Counter = Counter@30ab4b0e
scala> c increment 5 //中缀调用法
scala> c.getValue()     //getValue定义中有括号,可以带括号调用
res0: Int = 0
scala> c.getValue // getValue定义中有括号,也可不带括号调用
res1: Int = 0
scala> c.current() // current定义中没有括号,不可带括号调用
<console>:13: error: Int does not take parameters
       c.current()
                ^
scala> c.current  // current定义中没有括号,只能不带括号调用
res3: Int = 0
class Counter {
    var value = 0
    def increment(step:Int) = value += step //赋值表达式的值为Unit类型
    def current()= value //根据value的类型自动推断出返回类型为Int型
}
class Counter {
    var value = 0
def increment(step:Int) { value += step }
def current()= value
}
class Position(var x:Double=0,var y:Double=0) {
    def move(deltaX:Double=0,deltaY:Double=0) {
        x+=deltaX;
        y+=deltaY
    }
}
val p=new Position()
p.move(deltaY=5) //延y轴移动5个单位,deltaX采用了默认值
class Temp{
var x:Int = 0  //这里使用x作为字段名
def x(i:Int):Int=x+i  //这里又使用了同名的x作为方法名
}
def sumPowersOfTwo(a: Int, b: Int): Int = { 
        def powerOfTwo(x: Int): Int = {if(x == 0) 1 else 2 * powerOfTwo(x-1)}
        if(a > b) 0 else powerOfTwo(a) + sumPowersOfTwo(a+1, b)
}
class Counter(name: String) {
    private var value = 0    
    def increment(step: Int): Unit = { value += step}
    def current(): Int = {value}
    def info(): Unit = {printf("Name:%s",name)}
}
//代码文件为/usr/local/scala/mycode/Counter2.scala
class Counter {
    private var value = 0 
    private var name = ""
private var step = 1 //计算器的默认递进步长
println("the main constructor")
    def this(name: String){ //第一个辅助构造器
        this() //调用主构造器
        this.name = name
           printf("the first auxiliary constructor,name:%s\n",name)
    }
    def this (name: String,step: Int){ //第二个辅助构造器
        this(name) //调用前一个辅助构造器
        this.step = step
printf("the second auxiliary constructor,name:%s,step:%d\n",name,step)
    }
    def increment(step: Int): Unit = { value += step}
    def current(): Int = {value}
}
scala> :load /usr/local/scala/mycode/Counter2.scala
Loading /usr/local/scala/mycode/Counter2.scala…
defined class Counter
scala> val c1=new Counter
the main constructor
c1: Counter = Counter@319c6b2

scala> val c2=new Counter("the 2nd Counter")
the main constructor
the first auxiliary constructor,name:the 2nd Counter
c2: Counter = Counter@4ed6c602

scala> val c3=new Counter("the 3nd Counter",2)
the main constructor
the first auxiliary constructor,name:the 3nd Counter
the second auxiliary constructor,name:the 3nd Counter,step:2
c3: Counter = Counter@64fab83b
scala> class Counter(var name:String) //定义一个带字符串参数的简单类
defined class Counter
scala> var mycounter = new Counter("Runner")
mycounter: Counter = Counter@17fcc4f7
scala> println(mycounter.name) //调用读方法
Runner
scala> mycounter.name_=("Timer") //调用写方法
scala> mycounter.name = "Timer"// 更直观地调用写方法,和上句等效
mycounter.name: String = Timer
//代码文件为/usr/local/scala/mycode/Person.scala
object Person {
    private var lastId = 0  //一个人的身份编号
    def newPersonId() = {
        lastId +=1
        lastId
    }
}
scala> :load /usr/local/scala/mycode/Person.scala
Loading /usr/local/scala/mycode/Person.scala…
defined object Person
scala> printf("The first person id: %d.\n",Person.newPersonId())
The first person id: 1.
scala> printf("The second person id:%d.\n",Person.newPersonId())
The second person id:2.
scala> printf("The third person id: %d.\n",Person.newPersonId())
The third person id: 3.
//代码文件为/usr/local/scala/mycode/Person1.scala
class Person(val name:String){
    private val id = Person.newPersonId() //调用了伴生对象中的方法
    def info() {
        printf("The id of %s is %d.\n",name,id)
    }
}
object Person {
    private var lastId = 0  //一个人的身份编号
    def newPersonId() = {
        lastId +=1
        lastId
    }
    def main(args: Array[String]) {
        val person1 = new Person("Lilei")
        val person2 = new Person("Hanmei")
        person1.info()
        person2.info()
    }
}
scalac /usr/local/scala/mycode/Person1.scala
scala –classpath . Person
The id of Lilei is 1.
The id of Hanmei is 2.
val myStrArr = Array("BigData","Hadoop","Spark")
//代码文件为/usr/local/scala/mycode/TestApplyClass.scala
class TestApplyClass {
    def apply(param: String){
         println("apply method called: " + param)
}
}
scala> :load /usr/local/scala/mycode/TestApplyClass.scala
Loading /usr/local/scala/mycode/TestApplyClass.scala…
defined class TestApplyClass
scala> val myObject = new TestApplyClass
myObject: TestApplyClass = TestApplyClass@11b352e9
scala> myObject("Hello Apply")// 自动调用类中定义的apply方法,等同于下句
apply method called: Hello Apply
scala> myObject.apply("Hello Apply")  //手动调用apply方法
apply method called: Hello Apply
//代码文件为/usr/local/scala/mycode/MyTestApply.scala
class Car(name: String) {
    def info() {
        println("Car name is "+ name)
    }
}
object Car {
    def apply(name: String) = new Car(name) //调用伴生类Car的构造方法
}
object MyTestApply{
    def main (args: Array[String]) {
    val mycar = Car("BMW") //调用伴生对象中的apply方法         mycar.info() //输出结果为“Car name is BMW”
    }
}
scala> def add=(x:Int,y:Int)=>x+y  //add是一个函数
add: (Int, Int) => Int
scala> add(4,5)   //采用数学界的括号调用样式
res2: Int = 9
scala> add.apply(4,5) //add也是对象,采用点号形式调用apply方法
res3: Int = 9
scala> import scala.collection.mutable.Map //导入可变Map类
import scala.collection.mutable.Map
scala> val persons = Map("LiLei"->24,"HanMei"->21) 
persons: scala.collection.mutable.Map[String,Int] = …//省略部分信息
scala> persons("LiLei")=28 // 实际调用了Map的update方法,与下句等效
scala> persons.update("LiLei",28)
scala> persons("LiLei") // 实际是调用了Map的apply方法
res19: Int = 28
//代码文件为/usr/local/scala/mycode/TestUnapply.scala
class Car(val brand:String,val price:Int) {
    def info() {
        println("Car brand is "+ brand+" and price is "+price)
    }
}
object Car{
        def apply(brand:String,price:Int)= {
    println("Debug:calling apply ... ")
new Car(brand,price)
}
        def unapply(c:Car):Option[(String,Int)]={
      println("Debug:calling unapply ... ")
Some((c.brand,c.price))
}
}
object TestUnapply{
    def main (args: Array[String]) {
    var Car(carbrand,carprice) = Car("BMW",800000)
println("brand: "+carbrand+" and carprice: "+carprice)
    }
}
abstract class Car(val name:String) {
    val carBrand:String //字段没有初始化值,就是一个抽象字段
    def info() //抽象方法
    def greeting() {
        println("Welcome to my car!")
    }
}
//代码文件为/usr/local/scala/mycode/MyCar.scala
abstract class Car(val name:String) {
       val carBrand:String //一个抽象字段
var age:Int=0
    def info() //抽象方法
    def greeting() {
        println("Welcome to my car!")
    }
    def this(name:String,age:Int) {
        this(name)
        this.age=age
    }
}
//派生类,其主构造函数调用了父类的主构造函数
// 由于name是父类主构造器的参数,因此也必须override
class BMWCar(override val name:String) extends Car(name) {
    override val carBrand = "BMW"  //重载父类抽象字段,override可选
    def info() {//重载父类抽象方法,override关键字可选
        printf("This is a %s car. It has been used for %d year.\n", carBrand,age)
    }
  override def greeting() {//重载父类非抽象方法,override必选
        println("Welcome to my BMW car!")
    }
}
//派生类,其主构造函数调用了父类的辅助构造函数
class BYDCar(name:String,age:Int) extends Car(name,age) {
    val carBrand = "BYD" //重载父类抽象字段,override可选
    override def info() {//重载父类抽象方法,override关键字可选
        printf("This is a %s car.It has been used for %d year.\n", carBrand,age)
    }
}
object MyCar{
    def main(args:Array[String]) {
        val car1 = new BMWCar("Bob's Car")
        val car2 = new BYDCar("Tom's Car",3)
        show(car1)
        show(car2)
}
//将参数设为父类类型,根据传入参数的具体子类类型,调用相应方法,实现多态
    def show(thecar:Car)={thecar.greeting; thecar.info()}
}
def error(message:String): Nothing = throw new RuntimeException(message)
def divide(x:Int, y:Int): Int = 
  if(y != 0) x / y 
  else error("can't divide by zero") 
scala> case class Book(val name:String,val price:Double)
defined class Book
scala> val books=Map("hadoop"->Book("Hadoop",35.5),
     | "spark"->Book("Spark",55.5),
     | "hbase"->Book("Hbase",26.0)) //定义一个书名到书对象的映射
books: scala.collection.immutable.Map[String,Book] =… 
scala> books.get("hadoop") //返回该键所对应值的Some对象
res0: Option[Book] = Some(Book(Hadoop,35.5))
scala> books.get("hive") // 不存在该键,返回None对象
res1: Option[Book] = None
scala> books.get("hadoop").get //Some对象的get方法返回其包装的对象
res2: Book = Book(Hadoop,35.5)
scala> books.get("hive").get // None对象的get方法会抛出异常
java.util.NoSuchElementException: None.get
  …
scala> books.get("hive").getOrElse(Book("Unknown name",0))
res4: Book = Book(Unknown name,0.0)
//代码文件为/usr/local/scala/mycode/Box.scala
import scala.collection.mutable.Stack
class Box[T]{
    val elems:Stack[T]=Stack()
    def remove:Option[T]={ //返回的对象采用了Option类型进行包装
        if (elems.isEmpty) None else Some(elems.pop) 
    }
    def append(a1:T){elems.push(a1)}
}
scala> :load /usr/local/scala/mycode/Box.scala
Loading /usr/local/scala/mycode/Box.scala…
defined class Box
scala> case class Book(name:String) //定义了一个Book类
defined class Book
scala> val a = new Box[Book]//实例化一个元素为Book类型的Box实例并赋值给a
a: Box[Book] = Box@4e6f3d08
scala> a.append(Book("Hadoop"))//调用Box的append方法增加一个元素
scala> a.append(Book("Spark"))
scala> a.remove//调用Box的remove方法取出一个元素
res24: Option[Book] = Some(Book(Spark))
//代码文件为/usr/local/scala/mycode/Element.scala
abstract class Element{
type T //抽象的类型成员
       var value:T //抽象的字段,类型为T
       def show:Unit //抽象方法,需要根据具体的类型T进行实现
}
class IntEle(var value:Int) extends Element{
type T = Int
       def show{printf("My value is %d.\n",value)} //T是Int型时的输出
}
class StringEle(var value:String) extends Element{
type T = String
       def show{printf("My value is %s.\n",value)}//T是String型时的输出
}
scala> :load Element.scala
scala> val a=new IntEle(56)
a: IntEle = IntEle@58885a2e
scala> a.show
My value is 56.
scala> val b=new StringEle("hello")
b: StringEle = StringEle@6ecf239d
scala> b.show
My value is hello.
//代码文件为/usr/local/scala/mycode/Element1.scala
abstract class Element[T]{
var value:T
      def show:Unit
}
class IntEle(var value:Int) extends Element[Int]{
      def show{printf("My value is %d.\n",value)}
}
class StringEle(var value:String) extends Element[String]{
      def show{printf("My value is %s.\n",value)}
}
trait Flyable {
        var maxFlyHeight:Int  //抽象字段
     def fly() //抽象方法
def breathe(){ //具体的方法
      println("I can breathe")
  }
 }
trait T1{  //一个特质
     def move() //抽象方法
  }
trait T2extends T1 { 继承自T1
     def fly()  //抽象方法
def move(){println("I move by flying.")}//重载了父特质的抽象方法
  }
class Bird(flyHeight:Int) extends Flyable{
var maxFlyHeight:Int = flyHeight  //重载特质的抽象字段
     def fly(){
printf("I can fly at the height of %d.",maxFlyHeight)
} //重载特质的抽象方法
}
//代码文件为/usr/local/scala/mycode/Bird.scala
trait Flyable {
        var maxFlyHeight:Int  //抽象字段
     def fly() //抽象方法
def breathe(){ //具体的方法
         println("I can breathe")
     }
 }
class Bird(flyHeight:Int) extends Flyable{
var maxFlyHeight:Int = flyHeight  //重载特质的抽象字段
     def fly(){
printf("I can fly at the height of %d",maxFlyHeight)
} //重载特质的抽象方法
}
scala> :load /usr/local/scala/mycode/Bird.scala
Loading /usr/local/scala/mycode/Bird.scala...
defined trait Flyable
defined class Bird

scala> val b=new Bird(100)
b: Bird = Bird@43a51d00

scala> b.fly()
I can fly at the height of 100
scala> b.breathe()
I can breathe
scala> val t:Flyable=new Bird(50)
t: Flyable = Bird@149c39b
scala> t.fly //调用了Bird类的方法
I can fly at the height of 50
scala> t.breathe
I can breathe
//代码文件为/usr/local/scala/mycode/Bird1.scala
trait Flyable {
        var maxFlyHeight:Int  //抽象字段
     def fly() //抽象方法
def breathe(){ //具体的方法
         println("I can breathe")
     }
 }
class Animal(val category:String){
    def info(){println("This is a "+category)}
}
class Bird(flyHeight:Int) extends Animal("Bird") with Flyable{
var maxFlyHeight:Int = flyHeight //重载特质的抽象字段
     def fly(){
printf("I can fly at the height of %d",maxFlyHeight)
}//重载特质的抽象方法
}
scala> :load /usr/local/scala/mycode/Bird1.scala
Loading /usr/local/scala/mycode/Bird1.scala...
defined trait Flyable
defined class Animal
defined class Bird
scala> val b=new Bird(50)
b: Bird = Bird@5e1a7d3
scala> b.info  //调用了Animal类的info方法
This is a Bird
scala> b.fly //调用了Bird类的fly方法
I can fly at the height of 50
scala> b.breathe
I can breathe
//代码文件为/usr/local/scala/mycode/Bird2.scala
trait Flyable {
        var maxFlyHeight:Int  //抽象字段
     def fly() //抽象方法
def breathe(){ //具体的方法
         println("I can breathe")
     }
 }
trait HasLegs {
        val legs:Int   //抽象字段
     def move(){printf("I can walk with %d legs",legs)}
   }
class Animal(val category:String){
    def info(){println("This is a "+category)}
}
class Bird(flyHeight:Int) extends Animal("Bird") with Flyable with HasLegs{
var maxFlyHeight:Int = flyHeight //重载特质的抽象字段
val legs=2 //重载特质的抽象字段
     def fly(){
printf("I can fly at the height of %d",maxFlyHeight)
}//重载特质的抽象方法
}
scala> :load /usr/local/scala/mycode/Bird2.scala
Loading /usr/local/scala/mycode/Bird2.scala...
defined trait Flyable
defined trait HasLegs
defined class Animal
defined class Bird

scala> val b=new Bird(108)
b: Bird = Bird@126675fd
scala> b.info
This is a Bird
scala> b.fly
I can fly at the height of 108
scala> b.move
I can walk with 2 legs
//代码文件为/usr/local/scala/mycode/Bird3.scala
class Animal(val category:String){
    def info(){println("This is a "+category)}
}
trait HasLegs {
        val legs:Int   //抽象字段
     def move(){printf("I can walk with %d legs",legs)}
   }
scala> :load /usr/local/scala/mycode/Bird3.scala
Loading /usr/local/scala/mycode/Bird3.scala...
defined class Animal
defined trait HasLegs

scala> var a = new Animal("dog") with HasLegs{val legs = 4}
a: Animal with HasLegs = $anon$1@6f1fa1d0
scala> a.info
This is a dog
scala> a.legs
res24: Int = 4
scala> a.move
I can walk with 4 legs
//代码文件为/usr/local/scala/mycode/TestMatch.scala
import scala.io.StdIn._
println("Please input the score:")
val grade=readChar()
grade match{
    case 'A' => println("85-100")
    case 'B' => println("70-84")
    case 'C' => println("60-69")
    case 'D' => println("<60")
    case _ => println("error input!")
}
//代码文件为/usr/local/scala/mycode/TestMatch1.scala
import scala.io.StdIn._
println("Please input a country:")
val country=readLine()
country match{
        case "China" => println("中国")
        case "America" => println("美国")
        case "Japan" => println("日本")
        case _ => println("我不认识!")
}
//代码文件为/usr/local/scala/mycode/TestMatch2.scala
for (elem <- List(6,9,0.618,"Spark","Hadoop",'Hello)){
    val str  = elem match  {
        case i: Int => i + " is an int value."//匹配整型的值,并赋值给i
        case d: Double => d + " is a double value." //匹配浮点型的值
        case "Spark"=>"Spark is found." //匹配特定的字符串
        case s: String => s + " is a string value." //匹配其它字符串
        case _ =>"unexpected value:"+ elem  //与以上都不匹配
}
      println(str)
}
//代码文件为/usr/local/scala/mycode/TestMatch3.scala
for (elem <- List(1,2,3,4)){
elem match {
   case _ if (elem%2==0) => println(elem + " is even.")
case _ => println(elem + " is odd.")
}
}
case class Car(brand: String, price: Int)
object Car{
        def apply(brand:String,price:Int)= new Car(brand,price)
        def unapply(c:Car):Option[(String,Int)]=
Some((c.brand,c.price))
}
//代码文件为/usr/local/scala/mycode/TestCase.scala
case class Car(brand: String, price: Int) 
val myBYDCar = new Car("BYD", 89000)
    val myBMWCar = new Car("BMW", 1200000)
    val myBenzCar = new Car("Benz", 1500000)
    for (car <- List(myBYDCar, myBMWCar, myBenzCar)) {
        car match{
        case Car("BYD", 89000) => println("Hello, BYD!")
        case Car("BMW", 1200000) => println("Hello, BMW!")
        case Car(brand, price) => println("Brand:"+ brand +", Price:"+price+", do you want it?")   
        }
 }
scala> val Car(brand,price)=myBYDCar
brand: String = BYD
price: Int = 89000
scala> val Car(_,price)=myBYDCar
price: Int = 89000
package  autodepartment
class MyClass
package xmu {
  package autodepartment {
    class ControlCourse{
        ...
    }
  }
package csdepartment {
    class  OSCourse{
      val cc = new autodepartment.ControlCourse
    }
  }
}
import xmu.autodepartment.ControlCourse
class MyClass{
    var myos=new ControlCourse
}
import scala.io.StdIn._
var i=readInt()
var f=readFloat()
var str=readLine()
import java.lang._
import scala._
import Predef._
scala> val counter: (Int) => Int = { value => value + 1 }
counter: Int => Int = <function1>
scala> counter(5)
res2: Int = 6
val counter = (value:Int)=> value + 1
scala> val add=(a:Int,b:Int)=>a+b //函数类型为两个Int型参数,返回Int
add: (Int, Int) => Int = <function2>
scala> add(3,5)
res5: Int = 8
scala> val show=(s:String)=>println(s)//函数类型为一个String参数,返回Unit
show: String => Unit = <function1>
scala> show("hello world.")
hello world.
scala> val javaHome=()=>System.getProperty("java.home")
javaHome: () => String = <function0>//函数类型为无参数,返回String
scala> println(javaHome())
/usr/lib/jvm/java-8-openjdk-amd64/jre
scala> val counter = (_:Int) + 1 //有类型时括号不能省略,等效于“x:Int=>x+1”
counter: Int => Int = <function1>
scala> val add = (_:Int) + (_:Int) //等效于“(a:Int,b:Int)=>a+b”
add: (Int, Int) => Int = <function2>
scala> val m1=List(1,2,3)
m1: List[Int] = List(1, 2, 3)
scala>val m2=m1.map(_*2)//map接受一个函数作为参数,相当于“m1.map(x=>x*2)”,参数的类型可以根据m1的元素类型推断出,所以可以省略。
m2: List[Int] = List(2, 4, 6)
scala> def multiplier(factor:Int)(x:Int)=x*factor
multiplier: (x: Int)(factor: Int)Int //带有两个参数列表的函数
scala> multiplier(2)(5)
res2: Int = 10
def powerOfTwo(x: Int): Int = {if(x == 0) 1 else 2 * powerOfTwo(x-1)}
def sumInts(a: Int, b: Int): Int = {
        if(a > b) 0 else a + sumInts(a + 1, b)
}
def sumSquares(a: Int, b: Int): Int = {
        if(a > b) 0 else a*a + sumSquares(a + 1, b)
}
def sumPowersOfTwo(a: Int, b: Int): Int = {
        if(a > b) 0 else powerOfTwo(a) + sumPowersOfTwo(a+1, b)
}
def sum(f: Int => Int, a: Int, b: Int):Int = {
    if(a > b) 0 else f(a) + sum(f, a+1, b)
}
scala> sum(x=>x,1,5) //直接传入一个匿名函数
//且省略了参数x的类型,因为可以由sum的参数类型推断出来
res8: Int = 15
scala> sum(x=>x*x,1,5) //直接传入另一个匿名函数
res9: Int = 55
scala> sum(powerOfTwo,1,5) //传入一个已经定义好的方法
res10: Int = 62
scala> var more = 10
more: Int = 10
scala> val addMore =(x:Int)=> x + more
addMore: Int => Int = <function1>
scala> addMore(5) // more的值被绑定为10
res7: Int = 15
scala> more=20
more: Int = 20
scala> addMore(5)// more的值被绑定为20
res8: Int = 25
scala> var sum=0
sum: Int = 0
scala> val accumulator = (x:Int)=>sum+=x //包含外部变量sum的闭包
accumulator: Int => Unit = <function1>
scala> accumulator(5)
scala> sum
res13: Int = 5
scala> accumulator(10)
scala> sum
res15: Int = 15
scala> def sum(a:Int,b:Int,c:Int)=a+b+c
sum: (a: Int, b: Int, c: Int)Int
scala> val a=sum(1,_:Int,_:Int) //只保留了sum的后两个参数
a: (Int, Int) => Int = <function2>
scala> a(2,3) //等效于调用sum(1,2,3)
res0: Int = 6
scala> val b=sum _  //注意sum后有一个空格
b: (Int, Int, Int) => Int = <function3>
scala> b(1,2,3)
res1: Int = 6
scala> def multiplier(factor:Int)(x:Int)=x*factor
multiplier: (factor: Int)(x: Int)Int //带有两个参数列表的函数
scala> val byTwo=multiplier(2)_ //保留multiplier第二个参数的偏应用函数,//第一个参数值固定为2
scala> multiplier(2)(5)
res2: Int = 10
scala> byTwo(5)
res3: Int = 10
scala> def plainMultiplier(x:Int,y:Int)=x*y
plainMultiplier: (x: Int, y: Int)Int //带有两个参数的普通函数
scala> val curriedMultiplier = (plainMultiplier _).curried
curriedMultiplier: Int => (Int => Int) = <function1>
scala> plainMultiplier(2,5)
res5: Int = 10
scala> curriedMultiplier(2)(5)
res6: Int = 10
def foreach[U](f: Elem => U) :Unit
scala> val list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)
scala> val f=(i:Int)=>println(i)
f: Int => Unit = <function1>
scala> list.foreach(f)
1
2
3
scala> val university = Map("XMU" ->"Xiamen University", "THU" ->"Tsinghua University","PKU"->"Peking University")
university: scala.collection.mutable.Map[String,String] = ...
scala> university foreach{kv => println(kv._1+":"+kv._2)}
XMU:Xiamen University
THU:Tsinghua University
PKU:Peking University
university foreach{case (k,v) => println(k+":"+v)}
university foreach{x=>x match {case (k,v) => println(k+":"+v)}}
for(i<-list)println(i)
for(kv<- university)println(kv._1+":"+kv._2)
for((k,v)<- university)println(k+":"+v) //与上一句的效果一样
scala> val books =List("Hadoop","Hive","HDFS")
books: List[String] = List(Hadoop, Hive, HDFS)
scala> books.map(s => s.toUpperCase)
//toUpperCase方法将一个字符串中的每个字母都变成大写字母
res56: List[String] = List(HADOOP, HIVE, HDFS)
scala> books.map(s => s.length) //将字符串映射到它的长度
res57: List[Int] = List(6, 4, 4) //新列表的元素类型为Int
scala> books flatMap (s => s.toList)
res58: List[Char] = List(H, a, d, o, o, p, H, i, v, e, H, D, F, S)
scala> val university = Map("XMU" ->"Xiamen University", "THU" ->"Tsinghua University","PKU"->"Peking University","XMUT"->"Xiamen University of Technology")
university: scala.collection.immutable.Map[String,String] = ...

//过滤出值中包含“Xiamen”的元素,contains为String的方法
scala> val xmus = university filter {kv => kv._2 contains "Xiamen"}
universityOfXiamen: scala.collection.immutable.Map[String,String] = Map(XMU -> Xiamen University, XMUT -> Xiamen University of Technology)

scala> val l=List(1,2,3,4,5,6) filter {_%2==0}
//使用了占位符语法,过滤能被2整除的元素
l: List[Int] = List(2, 4, 6)
scala> val t=List("Spark","Hadoop","Hbase")
t: List[String] = List(Spark, Hadoop, Hbase)
scala> t exists {_ startsWith "H"} //startsWith为String的函数
res3: Boolean = true
scala> t find {_ startsWith "Hb"}
res4: Option[String] = Some(Hbase) //find的返回值用Option类进行了包装
scala> t find {_ startsWith "Hp"}
res5: Option[String] = None
scala> val list =List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)
scala>  list.reduce(_ + _) //将列表元素累加,使用了占位符语法
res16: Int = 15
scala>  list.reduce(_ * _) //将列表元素连乘
res17: Int = 120
scala> list map (_.toString) reduce ((x,y)=>s"f($x,$y)")
res5: String = f(f(f(f(1,2),3),4),5) //f表示传入reduce的二元函数
scala> val s1=Set(1,2,3)
s1: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
scala> val s2 = util.Random.shuffle(s1) //打乱集合的顺序生成一个新集合
s2: scala.collection.immutable.Set[Int] = Set(3, 2, 1)
scala> s1==s2 //s1和s2只是元素顺序不一样,但从集合的角度是完全相等的
res18: Boolean = true
scala> s1.reduce(_+_) //加法操作满足结合律和交换率,所以结果与遍历顺序无关
res19: Int = 6
scala> s2.reduce(_+_)
res20: Int = 6
scala> s1.reduce(_-_)//减法不满足结合律和交换率,与遍历顺序有关
res22: Int = -4
scala> s2.reduce(_-_)
res23: Int = 0
scala> val list = List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)
scala> list reduceLeft {_-_}
res24: Int = -13
scala> list reduceRight {_-_}
res25: Int = 3
scala> val s = list map (_.toString)  //将整型列表转换成字符串列表
s: List[String] = List(1, 2, 3, 4, 5)
scala> s reduceLeft {(accu,x)=>s"($accu-$x)"}
res28: String = ((((1-2)-3)-4)-5)//list reduceLeft{_-_}的计算过程
scala> s reduceRight {(x,accu)=>s"($x-$accu)"}
res30: String = (1-(2-(3-(4-5))))//list reduceRight{_-_}的计算过程
scala> val list =List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)
scala> list.fold(10)(_*_)
res32: Int = 1200
scala> (list fold 10)(_*_) //fold的中缀调用写法
res33: Int = 1200
scala> (list foldLeft 10)(_-_)//计算顺序(((((10-1)-2)-3)-4)-5)
res34: Int = -5 
scala> (list foldRight 10)(_-_) //计算顺序(1-(2-(3-(4-(5-10)))))
res35: Int = -7
scala> val em = List.empty
em: List[Nothing] = List()
scala> em.fold(10)(_-_)//对空容器fold的结果为初始值,对空容器调用reduce会报错
res36: Int = 10
scala> val list =List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)
scala> (list foldRight List.empty[Int]){(x,accu)=>x*2::accu}
res44: List[Int] = List(2, 4, 6, 8, 10) //与下面的map操作结果一样
scala> list map {_*2}
res45: List[Int] = List(2, 4, 6, 8, 10)
scala> val xs = List(1,2,3,4,5)
xs: List[Int] = List(1, 2, 3, 4, 5)
scala> val part = xs.partition(_<3)
part: (List[Int], List[Int]) = (List(1, 2),List(3, 4, 5))
scala> val gby = xs.groupBy(x=>x%3) //按被3整除的余数进行划分
gby: scala.collection.immutable.Map[Int,List[Int]] = Map(2 -> List(2, 5), 1 -> List(1, 4), 0 -> List(3))
scala> gby(2) //获取键值为2(余数为2)的子容器
res11: List[Int] = List(2, 5)
scala> val ged = xs.grouped(3) //拆分为大小为3个子容器
ged: Iterator[List[Int]] = non-empty iterator
scala> ged.next //第一个子容器
res3: List[Int] = List(1, 2, 3)
scala> ged.next //第二个子容器,里面只剩下两个元素
res5: List[Int] = List(4, 5)
scala> ged.hasNext //迭代器已经遍历完了
res6: Boolean = false
scala> val sl = xs.sliding(3)//滑动拆分为大小为3个子容器
sl: Iterator[List[Int]] = non-empty iterator
scala> sl.next //第一个子容器
res7: List[Int] = List(1, 2, 3)
scala> sl.next //第二个子容器
res8: List[Int] = List(2, 3, 4)
scala> sl.next//第三个子容器
res9: List[Int] = List(3, 4, 5)
scala> sl.hasNext //迭代器已经遍历完了
res10: Boolean = false
1   import java.io.File
2   import scala.io.Source
3   import collection.mutable.Map
4   object WordCount {
5       def main(args: Array[String]) {
6           val dirfile=new File("testfiles")
7           val files  = dirfile.listFiles
8           val results = Map.empty[String,Int]
9           for(file <-files) {
10              val data= Source.fromFile(file)
11              val strs =data.getLines.flatMap{s =>s.split(" ")}
12              strs foreach { word =>
13                          if (results.contains(word))
14                          results(word)+=1 else  results(word)=1
15                              }
16              }
17          results foreach{case (k,v) => println(s"$k:$v")}
18      }
19  }