今天继续学习了scala的一些知识,比如类与对象,抽象类等,还完成了spark实验二。
scala基础
(1)迭代器:迭代器(Iterator)不是一个集合,但是,提供了访问集合的一种方法。它包含两个函数:hasNext与next;hasNext可以判断迭代器是否还有下一个元素,next可以返回迭代器的下一个元素。
while循环
for循环
(2)class定义类,def定义方法
方法定义格式:def 方法名(参数名:参数类型): 返回值类型 = {函数体}
主构造器与辅助构造器:
主构造器是定义类时,类名后面标识参数类型与名称:
1 class Counter(val name: String, val mode: Int) { 2 private var value = 0 //value用来存储计数器的起始值 3 def increment(step: Int): Unit = { value += step} 4 def current(): Int = {value} 5 def info(): Unit = {printf("Name:%s and mode is %d ",name,mode)} 6 } 7 object MyCounter{ 8 def main(args:Array[String]){ 9 val myCounter = new Counter("Timer",2) 10 myCounter.info //显示计数器信息 11 myCounter.increment(1) //设置步长 12 printf("Current Value is: %d ",myCounter.current) //显示计数器当前值 13 } 14 }
辅助构造器是想java一样,在类内部实现,但是名称不是使用类名,而是this:
1 class Counter { 2 private var value = 0 //value用来存储计数器的起始值 3 private var name = "" //表示计数器的名称 4 private var mode = 1 //mode用来表示计数器类型(比如,1表示步数计数器,2表示时间计数器) 5 def this(name: String){ //第一个辅助构造器 6 this() //调用主构造器 7 this.name = name 8 } 9 def this (name: String, mode: Int){ //第二个辅助构造器 10 this(name) //调用前一个辅助构造器 11 this.mode = mode 12 } 13 def increment(step: Int): Unit = { value += step} 14 def current(): Int = {value} 15 def info(): Unit = {printf("Name:%s and mode is %d ",name,mode)} 16 } 17 object MyCounter{ 18 def main(args:Array[String]){ 19 val myCounter1 = new Counter //主构造器 20 val myCounter2 = new Counter("Runner") //第一个辅助构造器,计数器的名称设置为Runner,用来计算跑步步数 21 val myCounter3 = new Counter("Timer",2) //第二个辅助构造器,计数器的名称设置为Timer,用来计算秒数 22 myCounter1.info //显示计数器信息 23 myCounter1.increment(1) //设置步长 24 printf("Current Value is: %d ",myCounter1.current) //显示计数器当前值 25 myCounter2.info //显示计数器信息 26 myCounter2.increment(2) //设置步长 27 printf("Current Value is: %d ",myCounter2.current) //显示计数器当前值 28 myCounter3.info //显示计数器信息 29 myCounter3.increment(3) //设置步长 30 printf("Current Value is: %d ",myCounter3.current) //显示计数器当前值 31 32 } 33 }
getter与setter的使用方法
其实scala中也是险恶getter与setter方法的功能,但是没有定义为getter与setter:
1 class Counter { 2 private var privateValue = 0 //变成私有字段,并且修改字段名称 3 def value = privateValue //定义一个方法,方法的名称就是原来我们想要的字段的名称 4 def value_=(newValue: Int){ 5 if (newValue > 0) privateValue = newValue //只有提供的新值是正数,才允许修改 6 } 7 def increment(step: Int): Unit = { value += step} 8 def current(): Int = {value} 9 }
(3)特质(trait)
Scala中,一个类只能继承自一个超类,却可以实现多个特质,从而重用特质中的方法和字段,实现了多重继承。
特质跟继承不一样,特质可以包含非抽象字段或方法,一个类混入第一个特质使用extends,之后再混入使用with,例如:
1 class BYDCarId extends CarId with CarGreeting{ //使用extends关键字混入第1个特质,后面可以反复使用with关键字混入更多特质 2 override var id = 10000 //BYD汽车编号从10000开始 3 def currentId(): Int = {id += 1; id} //返回汽车编号 4 }
spark基础实验二
题目1:
源码:
1 import io.StdIn._ 2 3 object test{ 4 def main(args:Array[String]){ 5 var Sn:Float = 0 6 var n:Float = 1 7 print("请输入q:") 8 val q = readInt(); 9 while(Sn<q){ 10 Sn += (n+1)/n 11 n += 1 12 } 13 println("Sn="+Sn) 14 } 15 }
结果:
题目2
给出的代码:
1 case class Point(var x:Double,var y:Double) extends Drawable{ 2 def shift(deltaX:Double,deltaY:Double){x+=deltaX;y+=deltaY} 3 } 4 trait Drawable{ 5 def draw(){println(this.toString)} 6 } 7 // 请完成 Shape 类、Line 类和 Circle 类的定义。 8 abstract class Shape(var location:Point){//location是Shape的一个可变字段 9 def moveTo(newLocation:Point){ //默认实现,只是修改位置 10 location = newLocation 11 } 12 def zoom(scale:Double) 13 } 14 object MyDraw{ 15 def main(args: Array[String]) { 16 val p=new Point(10,30) 17 p.draw; 18 val line1 = new Line(Point(0,0),Point(20,20)) 19 line1.draw 20 line1.moveTo(Point(5,5)) //移动到一个新的点 21 line1.draw 22 line1.zoom(2) //放大两倍 23 line1.draw 24 val cir= new Circle(Point(10,10),5) 25 cir.draw 26 cir.moveTo(Point(30,20)) 27 cir.draw 28 cir.zoom(0.5) 29 cir.draw 30 } 31 } 32
完整代码:
1 case class Point(var x:Double,var y:Double) extends Drawable{ 2 def shift(deltaX:Double,deltaY:Double){x+=deltaX;y+=deltaY} 3 } 4 trait Drawable{ 5 def draw(){println(this.toString)} 6 } 7 // 请完成 Shape 类、Line 类和 Circle 类的定义。 8 abstract class Shape(var location:Point){//location是Shape的一个可变字段 9 def moveTo(newLocation:Point){ //默认实现,只是修改位置 10 location = newLocation 11 } 12 def zoom(scale:Double) 13 } 14 class Line(beginPoint:Point,var endPoint:Point) extends Shape(beginPoint) with Drawable{ 15 override def draw(){ 16 println("line:("+location.x+","+location.y+")--"+"("+endPoint.x+","+endPoint.y+")") 17 } 18 override def moveTo(newLocation:Point){ 19 endPoint.shift(newLocation.x - location.x,newLocation.y - location.y) //直线移动时,先移动另外一个端点 20 location = newLocation //移动位置 21 } 22 override def zoom(scale:Double){ 23 val midPoint = Point((endPoint.x + location.x)/2,(endPoint.y + location.y)/2) //求出中点,并按中点进行缩放 24 location.x = midPoint.x + scale * (location.x - midPoint.x) 25 location.y = midPoint.y + scale * (location.y -midPoint.y) 26 endPoint.x = midPoint.x + scale * (endPoint.x - midPoint.x) 27 endPoint.y = midPoint.y + scale * (endPoint.y -midPoint.y) 28 } 29 } 30 class Circle(center:Point,var radius:Double) extends Shape(center) with Drawable{ 31 override def draw(){//按指定格式重载click 32 println(s"Circle center:(${location.x},${location.y}),R=$radius") 33 } 34 override def zoom(scale:Double){ 35 radius = radius*scale //对圆的缩放只用修改半径 36 } 37 } 38 39 40 object MyDraw{ 41 def main(args: Array[String]) { 42 val p=new Point(10,30) 43 p.draw; 44 val line1 = new Line(Point(0,0),Point(20,20)) 45 line1.draw 46 line1.moveTo(Point(5,5)) //移动到一个新的点 47 line1.draw 48 line1.zoom(2) //放大两倍 49 line1.draw 50 val cir= new Circle(Point(10,10),5) 51 cir.draw 52 cir.moveTo(Point(30,20)) 53 cir.draw 54 cir.zoom(0.5) 55 cir.draw 56 } 57 } 58
结果截图:
题目3
1 object scoreReport 2 { 3 def main(args:Array[String]) 4 { 5 //假设数据在当前目录下 6 val inputFile=scala.io.Source.fromFile("test.txt") 7 8 //"\s"是字符串正则表达式,将每行按空白字符(包括空格/制表符)分开 9 //由于可能涉及多次遍历,通toList将Itertor装为List 10 //originalData的类型为List[Array[String]] 11 val originalData=inputFile.getLines.map{_.split{"\s+"}}.toList 12 13 val courseNames=originalData.head.drop(2) //获取第一行中的课程名 14 val allStudents=originalData.tail //去除第一行剩下的数据 15 val courseNum=courseNames.length 16 17 18 def statistc(lines:List[Array[String]])= 19 { 20 //for推导式,对每门课程生成一个三元组,分别表示总分,最低分和最高分 21 (for(i<- 2 to courseNum+1) yield 22 { 23 //取出需要统计的列 24 val temp =lines map{elem=>elem(i).toDouble} 25 (temp.sum,temp.min,temp.max) 26 })map{case(total,min,max)=>(total/lines.length,min,max)} //最后一个map对for的结果进行修改,将总分转为平均分 27 } 28 29 //输出结果函数 30 def printResult(theresult:Seq[(Double,Double,Double)]) 31 { 32 //遍历前调用zip方法将课程名容器和结果容器合并,合并结果为二元组容器 33 (courseNames zip theresult)foreach 34 { 35 case(course,result)=> 36 println(f"${course+":"}%-10s${result._1}%5.2f${result._2}%8.2f${result._3}%8.2f") 37 } 38 } 39 40 //分别调用两个函数统计全体学生并输出结果 41 val allResult=statistc(allStudents) 42 println("course average min max") 43 printResult(allResult) 44 //按性别划分为两个容器 45 val (maleLines,femaleLines)=allStudents partition 46 { 47 _(1)=="male" 48 } 49 50 //分别调用两个函数统计男学生并输出结果 51 val maleResult=statistc(maleLines) 52 println("course average min max") 53 printResult(maleResult) 54 55 //分别调用两个函数统计女学生并输出结果 56 val femaleResult=statistc(femaleLines) 57 println("course average min max") 58 printResult(femaleResult) 59 60 } 61 62 }
结果截图: