其他分享
首页 > 其他分享> > 2021-02-17 大数据课程笔记 day28

2021-02-17 大数据课程笔记 day28

作者:互联网

时间煮雨
@R星校长

Scala第二天【Scala内容】

主要内容

  1. Scala 迭代器模式处理数据
  2. ScalaTrait 特质特性
  3. Scala 模式匹配
  4. Scala 偏函数
  5. Scala 样例类
  6. Scala 隐式转换
  7. Scala Actor 通信模型
  8. Spark WordCount

学习目标在这里插入图片描述

第一节 Scala 迭代器模式 + Trait 特质特性

Scala迭代器模式处理数据

scala 中创建集合需要内存,集合与集合之间的转换时,每次转换生成新的集合时,新的集合也需要内存。如果有一个非常大的初始集合,需要经过多次转换,每次转换都生成一个新的集合,才能得到最终的结果,那么这时,在集合转换过程中内存开销非常大。Scala 迭代器模式处理数据,很好的解决了内存占用大的问题。
Scala 迭代器模式处理数据每次将集合的转换转变成了迭代器之间的转换,迭代器是不需要占用内存存储的,迭代器只是一个指针,指向了最初的原始数据,这样,数据处理过程中内存占用非常小。

迭代器模式处理示例:

1.	//非迭代器模式处理,浪费内存
2.	val list1 = List[String]("hello java","hello python","hello scala")
3.	val list2 = list1.flatMap(one=>{one.split(" ")})
4.	val list3 = list2.map(one=>{one+"#"})
5.	list3.foreach(println)
6.	
7.	println("********************")
8.	
9.	//迭代器模式处理,内存小
10.	val list = List[String]("hello java","hello python","hello scala")
11.	val iter1 = list.iterator
12.	val iter2 = iter1.flatMap(one=>{one.split(" ")})
13.	val iter3 = iter2.map(one=>{one+"#"})
14.	while(iter3.hasNext){
15.	  val one = iter3.next()
16.	  println(one)
17.	}

Trait 特质特性

  1. 概念理解
    Scala Trait (特质) 相当于 Java 的接口,实际上它比接口还功能强大。与接口不同的是,它还可以定义属性和方法的实现。
    一般情况下 Scala 的类可以继承多个 Trait,从结果来看就是实现了多重继承。第一个关键字使用 extends,之后使用 with。
    Trait (特质) 定义的方式与类类似,但它使用的关键字是 trait。
  2. 举例:trait 中带属性带方法实现
    注意:
1.	trait Read {
2.	  val readType = "Read"
3.	  val gender = "m"
4.	  def read(name:String){
5.	    println(name+" is reading")
6.	  }
7.	}
8.	
9.	trait Listen {
10.	  val listenType = "Listen"
11.	  val gender = "m"
12.	  def listen(name:String){
13.	    println(name + " is listenning")
14.	  }
15.	}
16.	
17.	class Person() extends Read with Listen{
18.	  override val gender = "f"
19.	}
20.	
21.	object test {
22.	  def main(args: Array[String]): Unit = {
23.	    val person = new Person()
24.	    person.read("zhangsan")
25.	    person.listen("lisi")
26.	    println(person.listenType)
27.	    println(person.readType)
28.	    println(person.gender)
29.	
30.	  }
31.	}
  1. 举例:trait 中带方法不实现
1.	object Lesson_Trait2 {
2.	  def main(args: Array[String]): Unit = {
3.	    val p1 = new Point(1,2)
4.	    val p2 = new Point(1,3)
5.	    println(p1.isEqule(p2))
6.	    println(p1.isNotEqule(p2))
7.	  }
8.	}
9.	
10.	trait Equle{
11.	  def isEqule(x:Any) :Boolean 
12.	  def isNotEqule(x : Any) = {
13.	     !isEqule(x)
14.	  }
15.	}
16.	
17.	class Point(x:Int, y:Int) extends Equle {
18.	  val xx = x
19.	  val yy = y
20.	
21.	  def isEqule(p:Any) = {
22.	    p.isInstanceOf[Point] && p.asInstanceOf[Point].xx==xx
23.	  }
24.	
25.	}

第二节 Scala 模式匹配+偏函数

模式匹配

  1. 概念理解:
    Scala 提供了强大的模式匹配机制,应用也非常广泛。
    一个模式匹配包含了一系列备选项,每个都开始于关键字 case。
    每个备选项都包含了一个模式及一到多个表达式。箭头符号 => 隔开了模式和表达式。
  2. 代码及注意点
1.	object Lesson_Match {
2.	  def main(args: Array[String]): Unit = {
3.	    val tuple = Tuple6(1,2,3f,4,"abc",55d)
4.	    val tupleIterator = tuple.productIterator
5.	    while(tupleIterator.hasNext){
6.	      matchTest(tupleIterator.next())
7.	    }
8.	  
9.	   }
10.	  /**
11.	   * 注意点:
12.	   * 1.模式匹配不仅可以匹配值,还可以匹配类型
13.	   * 2.模式匹配中,如果匹配到对应的类型或值,就不再继续往下匹配
14.	   * 3.模式匹配中,都匹配不上时,会匹配到 case _ ,相当于default
15.	   */
16.	  def matchTest(x:Any) ={
17.	    x match {
18.	      case x:Int=> println("type is Int")
19.	      case 1 => println("result is 1")
20.	      case 2 => println("result is 2")
21.	      case 3=> println("result is 3")
22.	      case 4 => println("result is 4")
23.	      case x:String => println("type is String")
24.	      // case x :Double => println("type is Double")
25.	      case _ => println("no match")
26.	    }
27.	  }
28.	
29.	}

偏函数

如果一个方法中没有 match 只有 case,这个函数可以定义成 PartialFunction 偏函数。偏函数定义时,不能使用括号传参,默认定义 PartialFunction 中传入一个值,匹配上了对应的 case,返回一个值,只能匹配同种类型。

1.	/**
2.	 * 一个函数中只有case 没有match ,可以定义成PartailFunction 偏函数
3.	 */
4.	 object Lesson_PartialFunction {
5.	  def MyTest : PartialFunction[String,String] = {
6.	     case "scala" =>{"scala"}
7.	     case "hello"=>{"hello"}
8.	     case _=> {"no match ..."}
9.	  }
10.	  def main(args: Array[String]): Unit = {
11.	     println(MyTest("scala"))
12.	  }
13.	}

第三节 Scala样例类+隐式转换

样例类(case classes)

  1. 概念理解
    使用了 case 关键字的类定义就是样例类 (case classes),样例类是种特殊的类。实现了类构造参数的 getter 方法(构造参数默认被声明为 val),当构造参数是声明为 var 类型的,它将帮你实现 setter 和 getter 方法。
  1. 例子:结合模式匹配的代码
1.	case class Person1(name:String,age:Int)
2.	
3.	object Lesson_CaseClass {
4.	  def main(args: Array[String]): Unit = {
5.	    val p1 = new Person1("zhangsan",10)
6.	    val p2 = Person1("lisi",20)
7.	    val p3 = Person1("wangwu",30)
8.	
9.	    val list = List(p1,p2,p3)
10.	    list.foreach { x => {
11.	       x match {
12.	          case Person1("zhangsan",10) => println("zhangsan")
13.	          case Person1("lisi",20) => println("lisi")
14.	          case _ => println("no match")
15.	       }
16.	    } }
17.	
18.	  }
19.	}

隐式转换

隐式转换是在 Scala 编译器进行类型匹配时,如果找不到合适的类型,那么隐式转换会让编译器在作用范围内自动推导出来合适的类型。

  1. 隐式值与隐式参数
    隐式值是指在定义参数时前面加上 implicit。隐式参数是指在定义方法时,方法中的部分参数是由 implicit 修饰【必须使用柯里化的方式,将隐式参数写在后面的括号中】。隐式转换作用就是:当调用方法时,不必手动传入方法中的隐式参数,Scala 会自动在作用域范围内寻找隐式值自动传入。

隐式值和隐式参数注意:

1). 同类型的参数的隐式值只能在作用域内出现一次,同一个作用域内不能定义多个类型一样的隐式值。
2). implicit 关键字必须放在隐式参数定义的开头
3). 一个方法只有一个参数是隐式转换参数时,那么可以直接定义 implicit 关键字修饰的参数,调用时直接创建类型不传入参数即可。
4). 一个方法如果有多个参数,要实现部分参数的隐式转换,必须使用柯里化这种方式,隐式关键字出现在后面,只能出现一次

1.	object Lesson_ImplicitValue {
2.	
3.	  def Student(age:Int)(implicit name:String,i:Int)= {
4.	    println( s"student :$name ,age = $age ,score = $i")
5.	  }
6.	  def Teacher(implicit name:String) ={
7.	    println(s"teacher name is = $name")
8.	  }
9.	
10.	  def main(args: Array[String]): Unit = {
11.	    implicit val zs = "zhangsan"
12.	    implicit val sr = 100
13.	
14.	    Student(18)
15.	    Teacher
16.	  }
17.	}
  1. 隐式转换函数
    隐式转换函数是使用关键字 implicit 修饰的方法。当 Scala 运行时,假设如果 A 类型变量调用了 method() 这个方法,发现 A 类型的变量没有 method() 方法,而 B 类型有此 method() 方法,会在作用域中寻找有没有隐式转换函数将 A 类型转换成 B 类型,如果有隐式转换函数,那么 A 类型就可以调用 method() 这个方法。
    隐式转换函数注意:隐式转换函数只与函数的参数类型和返回类型有关,与函数名称无关,所以作用域内不能有相同的参数类型和返回类型的不同名称隐式转换函数。
1.	class Animal(name:String){
2.	  def canFly(): Unit ={
3.	    println(s"$name can fly...")
4.	  }
5.	}
6.	class Rabbit(xname:String){
7.	  val name = xname
8.	}
9.	object Lesson_ImplicitFunction {
10.	
11.	  implicit def rabbitToAnimal(rabbit:Rabbit):Animal = {
12.	     new Animal(rabbit.name)
13.	  }
14.	
15.	  def main(args: Array[String]): Unit = {
16.	    val rabbit = new Rabbit("RABBIT")
17.	    rabbit.canFly()
18.	  }
19.	}
  1. 隐式类
    使用 implicit 关键字修饰的类就是隐式类。若一个变量 A 没有某些方法或者某些变量时,而这个变量 A 可以调用某些方法或者某些变量时,可以定义一个隐式类,隐式类中定义这些方法或者变量,隐式类中传入 A 即可。
    隐式类注意:
    1).隐式类必须定义在类,包对象,伴生对象中。
    2).隐式类的构造必须只有一个参数,同一个类,包对象,伴生对象中不能出现同类型构造的隐式类。
1.	class Rabbit(s:String){
2.	  val name = s
3.	}
4.	
5.	object Lesson_ImplicitClass {
6.	
7.	  implicit class Animal(rabbit:Rabbit){
8.	    val tp = "Animal"
9.	    def canFly() ={
10.	      println(rabbit.name +" can fly...")
11.	    }
12.	  }
13.	
14.	  def main(args: Array[String]): Unit = {
15.	    val rabbit = new Rabbit("rabbit")
16.	    rabbit.canFly()
17.	    println(rabbit.tp)
18.	  }
19.	}

第四节 Scala Actor 通信模型

  1. 概念理解
  1. 例:Actor简单例子发送接收消息
1.	import scala.actors.Actor
2.	
3.	class myActor extends Actor{
4.	
5.	  def act(){
6.	    while(true){
7.	      receive {
8.	        case x:String => println("get String ="+ x)
9.	        case x:Int => println("get Int")
10.	        case _ => println("get default")
11.	      }
12.	    }
13.	  }
14.	}
15.	
16.	object Lesson_Actor {
17.	  def main(args: Array[String]): Unit = {
18.	
19.	    //创建actor的消息接收和传递
20.	    val actor =new myActor()
21.	    //启动
22.	    actor.start()
23.	    //发送消息写法
24.	    actor ! "i love you !"
25.	
26.	  }
27.	}
  1. 例:Actor 与 Actor 之间通信
1.	case class Message(actor:Actor,msg:Any)
2.	
3.	class Actor1 extends Actor{
4.	  def act(){
5.	    while(true){
6.	      receive{
7.	        case msg :Message => {
8.	          println("i sava msg! = "+ msg.msg)
9.	
10.	          msg.actor!"i love you too !"
11.	        }
12.	        case msg :String => println(msg)
13.	        case _ => println("default msg!")
14.	      }
15.	    }
16.	  }
17.	}
18.	
19.	class Actor2(actor :Actor) extends Actor{
20.	  actor ! Message(this,"i love you !")
21.	  def act(){
22.	    while(true){
23.	      receive{
24.	        case msg :String => {
25.	         if(msg.equals("i love you too !")){
26.	            println(msg)
27.	            actor! "could we have a date !"
28.	         }
29.	        }
30.	        case _ => println("default msg!")
31.	      }
32.	    }
33.	  }
34.	}
35.	
36.	object Lesson_Actor2 {
37.	  def main(args: Array[String]): Unit = {
38.	    val actor1 = new Actor1()
39.	    actor1.start()
40.	    val actor2 = new Actor2(actor1)
41.	    actor2.start()
42.	  }
43.	}

第五节 WordCount

  1. 创建 Maven 项目导入 pom.xml 文件
    安装 Maven 仓库管理工具,版本要求是 3.2 版本以上。新建 Maven 项目,配置 pom.xml。导入必要的包。
  2. Spark-Scala 版本的 WordCount
1.	val conf = new SparkConf()
2.	conf.setMaster("local")
3.	conf.setAppName("scala-wc")
4.	val sc = new SparkContext(conf)
5.	val lines = sc.textFile("./data/words")
6.	val words = lines.flatMap(line=>{line.split(" ")})
7.	val pairWords = words.map(word=>{new Tuple2(word,1)})
8.	val result = pairWords.reduceByKey((v1:Int,v2:Int)=>{v1+v2})
9.	result.foreach(println)
  1. Spark-Java 版本的 WordCount
1.	SparkConf conf = new SparkConf();
2.	conf.setMaster("local");
3.	conf.setAppName("java-wc");
4.	JavaSparkContext sc = new JavaSparkContext(conf);
5.	JavaRDD<String> lines = sc.textFile("./data/words");
6.	JavaRDD<String> words = lines.flatMap(new   FlatMapFunction<String, String>() {
7.	  @Override
8.	  public Iterator<String> call(String s) throws Exception {
9.	    String[] split = s.split(" ");
10.	    return Arrays.asList(split).iterator();
11.	  }
12.	});
13.	JavaPairRDD<String, Integer> pairWords = words.mapToPair(new PairFunction<String, String, Integer>() {
14.	  @Override
15.	  public Tuple2<String, Integer> call(String word) throws Exception {
16.	    return new Tuple2<>(word, 1);
17.	  }
18.	});
19.	JavaPairRDD<String, Integer> result = pairWords.reduceByKey(new Function2<Integer, Integer, Integer>() {
20.	  @Override
21.	  public Integer call(Integer v1, Integer v2) throws Exception {
22.	    return v1 + v2;
23.	  }
24.	});
25.	result.foreach(new VoidFunction<Tuple2<String, Integer>>() {
26.	  @Override
27.	  public void call(Tuple2<String, Integer> tuple2) throws  Exception {
28.	    System.out.println(tuple2);
29.	  }
30.	});
31.	sc.stop();

本节作业

  1. 掌握Scala迭代器处理数据模式
  2. 掌握Trait特质特性
  3. 掌握Scala 模式匹配
  4. 掌握Scala隐式转换
  5. 了解Actor通信模型
  6. 了解Spark WordCount
  7. 所有代码至少敲一遍

标签:02,case,day28,val,Scala,17,println,隐式,String
来源: https://blog.csdn.net/qq_44745905/article/details/113831407