zoukankan      html  css  js  c++  java
  • scala04

    scala04课件

    作业题

    object HomeWorke232424r {
        def main(args: Array[String]): Unit = {
          val d1 = Array(("bj", 28.1), ("sh", 28.7), ("gz", 32.0), ("sz", 33.1))
          val d2 = Array(("bj", 27.3), ("sh", 30.1), ("gz", 33.3))
          val d3 = Array(("bj", 28.2), ("sh", 29.1), ("gz", 32.0), ("sz", 30.5))

          val d4:Array[(String,Double)] = d1++d2++d3

          val groupedData:Map[String,Array[(String,Double)]] = d4.groupBy(_._1)

    //      val result:Map[String,Double] = groupedData.mapValues(t=>t.map(_._2).sum/t.length)

          val result:Map[String,(String,Double)] = groupedData.mapValues(t=>t.reduce((a,b)=>("",a._2+b._2)))

          result.foreach(t=>println(t._1,t._2._2.formatted("%.1f")))
        }
    }

    object homework1{
      def main(args: Array[String]): Unit = {
        val pattern = Pattern.compile("[- ]")
        val lst = List("Id1-The Spark", "Id2-The Hadoop", "Id3-The Spark")
    //  flatten flatMap  Array((spark,id1),(the,id1),(the,id2))
        //spark-id1 id3
        //The-id1 id2 id3
        val tupleList:List[(String,String)]=lst.flatMap(t=>{
           val strs:Array[String] = pattern.split(t)
           val tuples:Seq[(String,String)] =  for(e<-1 to strs.length-1)yield (strs(e),strs(0))
           tuples
        })
       val groupedData:Map[String,List[(String,String)]] =  tupleList.groupBy(_._1)

        //The - id1  id2  id3
    //    val result:Map[String,String] = groupedData.mapValues(t=>t.map(_._2).mkString(" "))
        val result:Map[String,(String,String)] = groupedData.mapValues(t=>t.reduce((a,b)=>("",a._2+" "+b._2)))
        result.foreach(t=>println(t._1+"-"+t._2._2))
      }
    }

    reduce  reduceLeft  reduceRight

    reduce底层使用的是reduceLeft,但是reduce不可以类型不一样reduce中放入的函数,参数返回值类型必须一致,并且这个类型是集合中元素的本泛型或者是父泛型

    reduceLeft中函数的参数泛型和返回值的泛型必须保持父子关系,返回值和参数可以不一样,但是必须是父类的关系

    scala> var arr = Array(1,2,3,4,5,6,7,8)

    arr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8)

    scala> arr.reduce(_+_)

    res0: Int = 36

    scala> arr.reduceLeft(_+_)

    res1: Int = 36

    scala> arr.reduceRight(_+_)

    res2: Int = 36

    scala> arr.reduce(_-_)

    res3: Int = -34

    scala> arr.reduceLeft(_-_)

    res4: Int = -34

    scala> arr.reduceRight(_-_)

    reduceRight的归并顺序是从又向左,但是计算顺序还是左右

    fold  foldLeft  foldRight归并

    scala> var arr = Array(("hello",1),("word",1),("c",1))

    arr: Array[(String, Int)] = Array((hello,1), (word,1), (c,1))

    scala> arr.fold(0)((a,b)=>a+b._2)

    <console>:13: error: value _2 is not a member of Any

           arr.fold(0)((a,b)=>a+b._2)

                                  ^

    scala> arr.fold(0)((a,b)=>a+b.asInstanceOf[(String,Int)]._2)

    <console>:13: error: type mismatch;

     found   : Int

     required: String

           arr.fold(0)((a,b)=>a+b.asInstanceOf[(String,Int)]._2)

                                                             ^

    scala> arr.fold(0)((a,b)=>a.asInstanceOf[Int]+b.asInstanceOf[(String,Int)]._2)

    res12: Any = 3

    scala> var arr = Array(1,2,3,4)

    arr: Array[Int] = Array(1, 2, 3, 4)

    scala> var arr1 = Array(arr,arr,arr)

    arr1: Array[Array[Int]] = Array(Array(1, 2, 3, 4), Array(1, 2, 3, 4), Array(1, 2, 3, 4))

    scala> arr1.fold(Array[Int]())((a,b)=>a++b)

    res13: Array[Int] = Array(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4)

    def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op)

    fold的底层使用的是foldLeft

    def foldLeft[B](z: B)(op: (B, A) => B): B = {
      var result = z
      this foreach (x => result = op(result, x))
      result
    }

    foldLeft的泛型可以是不同的泛型,而且泛型间没有父子关系

    scala> arr1.fold(0)((a,b)=>a+b.sum)

    <console>:14: error: value sum is not a member of Any

           arr1.fold(0)((a,b)=>a+b.sum)

                                   ^

     

    scala> arr1.foldLeft(0)((a,b)=>a+b.sum)

    res15: Int = 30

     

    scala> var arr = Array(("hello",1),("word",1),("c",1))

    arr: Array[(String, Int)] = Array((hello,1), (word,1), (c,1))

     

    scala> arr.foldLeft(0)((a,b)=>a+b._2)

    res16: Int = 3

     

    foldRight(0)()

    scala> var arr = Array(1,2,3,4,5,6,7)

    arr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7)

    scala> arr.foldRight(0)(_-_)

    res22: Int = 4

    scala> arr.foldLeft(0)(_-_)

    res23: Int = -28

    aggregate

    聚合方法

    def aggregate[B](z: =>B)(seqop: (B, A) => B, combop: (B, B) => B): B = foldLeft(z)(seqop)

    源码中aggregate聚合函数中,第一值是初始化的,第二是聚合函数,第三个没用

    底层调用的是foldLeft

    scala> arr.aggregate

       def aggregate[B](z: => B)(seqop: (B, Int) => B,combop: (B, B) => B): B

    scala> arr.aggregate(0)(_+_,_+_)

    res24: Int = 28

    scala> arr.aggregate(0)(_+_,_*_)

    res25: Int = 28

    scala> arr.aggregate(0)(_+_,_/_)

    res26: Int = 28

    scala> arr.aggregate(0)(_+_,Null)

    <console>:13: error: not found: value Null

           arr.aggregate(0)(_+_,Null)

                                ^

    scala> arr.aggregate(0)(_+_,null)

    res28: Int = 28

    aggregate是聚合函数其中第二个聚合函数在spark中有意义,在spark中第二个函数是全局聚合的含义

    Take方法

    scala> var arr = Array(1,2,3,4,5,6,7,8)

    arr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8)

    scala> arr.take(3)

    res29: Array[Int] = Array(1, 2, 3)

    scala> arr.take(4)

    res30: Array[Int] = Array(1, 2, 3, 4)

    slice切分集合

    scala> arr

    res31: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8)

    scala> arr.slice(0,3)

    res32: Array[Int] = Array(1, 2, 3)

    scala> arr.slice(5,3)

    res33: Array[Int] = Array()

    scala> arr.slice(5,6)

    res34: Array[Int] = Array(6)

    scala中的面向对象

    面向对象三大特性  封装(方法)  继承(extends implements)  多态(继承)

    接口 interface  abstract抽象类 class

    scala  trait abstract object class

    scala 中的对象object

    object就是一个static的类,object是单例的,和javastatic修饰的东西一样,可以用来代替staticobject的对象不能new,所以全局只有初始化的时候声明的第一个实例

    class abc{
      def main(args: Array[String]): Unit = {
        println(123)
      }
    }

    class修饰的main方法是不能运行的,因为不是static的,object修饰的类相当于在java中的static{}静态代码块

    scalaobject对象在编译的时候会生成两个类,一个是普通的类,一个是带有$的虚类

    普通的类中的修饰父是final形式的,所以这个object的类不能new,普通的object编译出来的类只有一个main方法,虚类中会存在很多的逻辑代码,虚类中在启动的时候static{new()}

    在加载的时候首先new出来一个对象

    object的使用

    创建object与创建类是一样的,object中可以定义方法,可以定义属性

    object test321{
      def main(args: Array[String]): Unit = {
        println(user)
        println(user)
        println(user)
        println(user)
      }

    }
    object user{
      println(123)
    }

     

    123

    user$@140d5f0

    user$@140d5f0

    user$@140d5f0

    user$@140d5f0

    object使用的时候可以直接写object的名字,而且使用多次都是一个对象,但是这个对象只会被加载一次,object编译后的文件是一个static修饰的,所以我们在调用object的时候会执行其中的代码

    伴生对象

    在一个文件中名称相同的类和对象,那么这个类就是这个对象的伴生类,这个对象就是这个类的伴生对象,他们之间互为伴生

    伴生对象可以访问伴生类中的私有属性和方法

    class user{
      private val name = "赵四"
      private def getHello={
        println("hello")
      }
    }

    object student{
      def main(args: Array[String]): Unit = {
         val u = new user()
        val stu = new student
        stu.getHello
        stu.name
      }
    }
    class student{
      private def getHello={
        println("hello")
      }
      private val name = "刘能"
    }

     

    一般情况下我们都会创建对象的时候创建一个伴生的类

    重点是在伴生对象中存在一个apply的方法

    object testtt{
      def main(args: Array[String]): Unit = {
        val stu = new student
        val stu1 = student()
        println(student("志玲"))
      }
    }
    object student{
      def apply(): student = new student()
      def apply(name:String): String = "hi girl,u r "+name+"?"
      def main(args: Array[String]): Unit = {
         val u = new user()
        val stu = new student
        stu.getHello
        stu.name
      }
    }

    apply方法的特殊性是因为apply方法的名字,可以进行重载,调用apply方法object()

    var stu:student = null
    def apply(): student = {
      if(stu==null)
        stu=new student
      stu
    }

    其实可以通过私有构造器,然后重写伴生对象中的apply方法进行单例模式的创建

    对象和实例的泛型

    val stu: student = new student
    val stu1: student = student()
    val stu2: student.type = student

    new出来的实例,泛型是class  对象的泛型是object.type

    应用程序方法:

    object testtt extends App{

      println(123)
      println(123)
      println(123)

      override def main(args: Array[String]): Unit = {
        println(234)
      }
      println(123)
      println(123)
      println(123)

    }

    一个object对象继承了App接口,那么这个接口中的main就可以将整个object中的代码全部都包含,如果在子类中重写了这个main方法,那么这个类中的其他代码就不会执行了

    class类,new class()所产生东西叫做类的实例

    类中可以声明方法和属性

    public class Teacher

    {

      private String name = "谢永强";

      private final int age = 40;

      public String name()

      {

        return this.name; }

      public void name_$eq(String x$1) { this.name = x$1; }

      public int age() { return this.age; }

      public void getHello() {

        Predef..MODULE$.println("hello");

      }

    }

    class Teacher{
      var name:String = _
      var age:Int = _
      val sex="男"
      def getHello(): Unit ={
        println("hello")
      }
    }

    object trrr{
      def main(args: Array[String]): Unit = {
        val tea = new Teacher
        tea.name = "刘德华"
        println(tea.age)
        println(tea.name)
        tea.getHello()
      }
    }

    var声明的属性一般都是带有set get方法的,val修饰的都是用final修饰的,只能存在get方法没有set方法
    override def toString:String = s"name=${name}  age=${age}  sex= ${sex}"

    s插值法,在字符串前面加上s,字符串中就可以使用${}进行取值

    构造器:

    scala中的构造器类似于java中的构造器

    构造器主要分为两类,主构造器,辅助构造器

    主构造器是在类后面的构造器

    object trrr{
      def main(args: Array[String]): Unit = {
          val t = new tobacco()
          val t1 = new tobacco("红塔山","渣渣",7.5)
      }
    }
    class tobacco(logo:String,smell:String,price:Double){
    }

    主构造器在没有声明的时候就是一个空参构造器,如果构造器声明了,那么空参构造器就被覆盖掉了

    object trrr{
      def main(args: Array[String]): Unit = {
          val t1 = new tobacco("红塔山","渣渣",7.5)
          println(t1.logo)
      }
    }
    class tobacco(var logo:String,smell:String,price:Double){
    }

     

    object trrr{
      def main(args: Array[String]): Unit = {
          val t1 = new tobacco("红塔山","渣渣",7.5)
          println(t1)
      }
    }
    class tobacco(var logo:String,smell:String,price:Double){
      override def toString: String = s"${logo}  ${smell}  ${price}"
    }

     

    在创建构造器的时候一定要指定val/var进行修饰,不然的话这个数据就是参数不是属性值,没有办法取值,作为参数传递到类中的值,可以在类内部使用

    在一个类中构造器的参数和数据的名称不能重复

    辅助构造器

    class tobacco(var logo:String,smell:String,price:Double){
            def this(){
              //辅助构造器的第一行内容必须调用构造器
              this("芙蓉王","香",25)
            }
    }

    辅助构造器的第一行必须调用其他的构造器

     

  • 相关阅读:
    SQL Activity Monitor
    Oracle学习计划
    SQL Server 2008 R2下载地址
    聚集索引与非聚集索引的区别
    Android图片加载后变小
    工作手记之Cransoft(四)
    触发器
    Oracle数据库体系架构概要
    html5
    基础概念
  • 原文地址:https://www.cnblogs.com/JBLi/p/11527144.html
Copyright © 2011-2022 走看看