大数据进阶之路——Scala 函数和对象

本文涉及的产品
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
简介: 大数据进阶之路——Scala 函数和对象

@[toc]

函数

方法定义

    def 方法名(参数: 参数类型): 返回值类型 = {
        //方法体

        //最后一行作为返回值(不需要使用return)
    }

    def max(x: Int, y: Int): Int = {
        if(x > y)
            x
        else 
            y
    }

package org.example

object App {

  def main(args: Array[String]): Unit = {
    println(add(2,5))
  }


  def add(x:Int,y:Int):Int={
  x+y
  }
}
7
package org.example

object App {

  def main(args: Array[String]): Unit = {

    println(three())
    //没有入参的时候可以不用写
    println(three)
  }




  def three()=1+2
}

无返回值 自动加Unit

默认参数

默认参数: 在函数定义时,允许指定参数的默认值
  //参数
  def sayName(name: String ) = {
    println(name)
  }

  //默认参数
  def sayName1(name: String ="Jack") = {
    println(name)
  }


//main调用

    sayName("jaja")
    sayName1()
    sayName1("Ma")
jaja
Jack
Ma
相关源码:SparkContext中使用

命名参数

可以修改参数的传入 顺序

      def speed(destination: Float, time: Float): Float {
          destination / time
      }

      println(speed(100, 10))
      println(speed(time = 10, destination = 100))

可变参数

变参数(可传入任意多个相同类型的参数) java中 int... numbers
JDK5+:可变参数
    def sum(number: Int*) =  {
        var result = 0
        for(num <- number) {
            result += num
        }
        result
    }
相关源码:org.apache.spark.sql.Dataset中的select方法



条件语句

循环语句

  • to 1 to 10 (左闭右闭) 1.to(10)
  • range Range(1,10) (左闭右开的) Range(1,10,2) (2为步长)
  • until 1 until 10 (左闭右开)

to、until的底层调用都是Range

scala> 1 to 10
res1: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> Range(1,10)
res2: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> 1.to(10)
res3: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> Range(1,10,2)
res4: scala.collection.immutable.Range = Range(1, 3, 5, 7, 9)

scala> Range(1,10,5)
res5: scala.collection.immutable.Range = Range(1, 6)

scala> Range(10,1,-1)
res8: scala.collection.immutable.Range = Range(10, 9, 8, 7, 6, 5, 4, 3, 2)

scala> 1 until 10
res9: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
  • for
    for(i <- 1.to(10)) {
        println(i)
    }
    for(i <- 1.until(10, 2)) {
        println(i)
    }
    for(i <- 1 to 10 if i % 2 == 0) {
        println(i)
    }

    val courses = Array("Hadoop", "Spark SQL", "Spark Streaming", "Storm", "Scala")
    for(x<- courses) {
        println(x)
    }

    //x其实就是courses里面的每个元素
    // =>      就是将左边的x作用上一个函数,变成另外一个结果


    courses.foreach(x=> println(x))
  • while
    var (num, sum) = (100, 0)
    while(num > 0){
        sum = sum + num
        num = num - 1
    }
    println(sum)

面向对象

概述

  • Java/Scala OO(Object Oriented)

    • 封装:属性、方法封装到类中,可设置访问级别
    • 继承:父类和子类之间的关系 重写
    • 多态:父类引用指向子类对象 开发框架基石
Person person = new Person();
User user = new User();
Person person =new User();

类的定义和使用


package org.example

object ObjectApp {
  def main(args: Array[String]): Unit = {
    val person = new People()
    person.name = "Messi"
    //    println(person.name + ".." + person.age)
    println("invoke eat method: " + person.eat)
    person.watchFootball("Barcelona")

    person.printInfo()
    //编译不通过 private 修饰
    //    println(person.gender)
  }

}



class People{
  //var(变量)类型自动生成getter/setter
  //这种写法就是一个占位符
  var name: String = _
  //val(常量)类型自动生成getter
  val age: Int = 10

  private [this] var gender = "male"

  def printInfo() : Unit = {
    print("gender: " + gender)
  }

  def eat(): String = {
    name + " eat..."
  }

  def watchFootball(teamName: String): Unit = {
    println(name + " is watching match of " + teamName)
  }
}


invoke eat method: Messi eat...
Messi is watching match of Barcelona
gender: male

继承和重写

  • 继承

class Student(name: String, age: Int, var major: String) extends Person(name, age) {}

  • 重写
    override def acquireUnrollMemory()
    override def toString = "test override"
package org.example

object ConstructorApp {
  def main(args: Array[String]): Unit = {
    var person =new Person("zhangsan",99)
    println(person.age+":"+person.name)
    var person2 =new Person("zhangsan",99,"Man")
    println(person2.age+":"+person2.name+";"+person2.gender)
  }

}
//主构造器
class Person(val name: String, val age: Int){
  println("Person constructor enter...")

  val school = "ustc"
   //占位符肯定要预先指定类型
  var gender: String = _

  //附属构造器
  def this(name: String , age: Int, gender: String){
    //必须要调用主构造器或者其他附属构造器
    this(name, age)
    this.gender = gender
  }

  override def toString = "test override"
  println("Person Constructor leave...")

}

//继承
//name: String, age: Int, var major: String 继承父类的可以不用直接写var 否则需要重新申明
class Student(name: String, age: Int, var major: String) extends Person(name, age) {

  //重写
  override val school = "pku"
  println("Person Student enter...")

  println("Person Student leave...")
}

抽象类

package org.example

object AbstractApp {
  def main(args: Array[String]): Unit = {
    var stu =new Student1();
    println(stu.age)
    println(stu.name)
    stu.speak;
  }
}
abstract class Person3{
  def speak

  val name: String
  val age: Int
}

class Student1 extends Person3{
  override def speak: Unit = {
    println("speak")
  }
  override val name: String = "Messi"
  override val age: Int = 32
}

伴生类和伴生对象

如果有一个 class,还有一个与 class同名的 object 互为 伴生类和伴生对象
    class ApplyTest{
        def apply(){
            println(...)
        }
    } 
    object ApplyTest{
        def apply(){
            println("Object ApplyTest apply...")
            new ApplyTest
        }
    } 
类名() ==> Object.apply
  对象() ==> Class.apply  
  最佳实践:在Object的apply方法中去new一个Class

package org.example


object ApplyApp {
  def main(args: Array[String]): Unit = {
//    for(i<-1 to 10){
//      ApplyTest.incr
//    }
//    //object 是一个单例对象
//    println(ApplyTest.count)

    var b=ApplyTest()
    //默认走的是object=》apply
    //Object ApplyTest apply...

    println("-----------------------")
    var c= new ApplyTest()
    c()
    //Class ApplyTest apply...
  }

}
class ApplyTest {
  def apply() = {
    println("Class ApplyTest apply...")

  }

}
object ApplyTest {
  println("Object start...")
  var count = 0
  def incr={
    count=count+1
  }
  def apply() = {
    println("Object ApplyTest apply...")

    //在object中的apply中new class
    new ApplyTest
  }
  println("Object end...")
}

case和trait

case class :不用new

case class Dog(name: String)
直接可以调用Dog("wangcai")

Trait: 类似implements
xxx entends ATrait 
xxx extends Cloneable with Logging with Serializable
源码中Partition类

相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
目录
相关文章
|
1月前
|
消息中间件 分布式计算 NoSQL
大数据-104 Spark Streaming Kafka Offset Scala实现Redis管理Offset并更新
大数据-104 Spark Streaming Kafka Offset Scala实现Redis管理Offset并更新
40 0
|
1月前
|
消息中间件 存储 分布式计算
大数据-103 Spark Streaming Kafka Offset管理详解 Scala自定义Offset
大数据-103 Spark Streaming Kafka Offset管理详解 Scala自定义Offset
82 0
|
16天前
|
SQL 存储 算法
基于对象 - 事件模式的数据计算问题
基于对象-事件模式的数据计算是商业中最常见的数据分析任务之一。对象如用户、账号、商品等,通过唯一ID记录其相关事件,如操作日志、交易记录等。这种模式下的统计任务包括无序计算(如交易次数、通话时长)和有序计算(如漏斗分析、连续交易检测)。尽管SQL在处理无序计算时表现尚可,但在有序计算中却显得力不从心,主要原因是其对跨行记录运算的支持较弱,且大表JOIN和大结果集GROUP BY的性能较差。相比之下,SPL语言通过强化离散性和有序集合的支持,能够高效地处理这类计算任务,避免了大表JOIN和复杂的GROUP BY操作,从而显著提升了计算效率。
|
1月前
|
Java 大数据 数据库连接
大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala
大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala
29 2
大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala
|
24天前
|
SQL 存储 算法
基于对象 - 事件模式的数据计算问题
基于对象-事件模式的数据计算是商业中最常见的数据分析任务之一。这种模式涉及对象(如用户、账户、商品等)及其相关的事件记录,通过这些事件数据可以进行各种统计分析,如漏斗分析、交易次数统计等。然而,SQL 在处理这类任务时表现不佳,特别是在有序计算方面。SPL 作为一种强化离散性和有序集合的语言,能够高效地处理这类计算,避免了大表 JOIN 和大结果集 GROUP BY 的性能瓶颈。通过按 ID 排序和分步计算,SPL 能够显著提高计算效率,并支持实时数据处理。
|
1月前
|
消息中间件 存储 druid
大数据-156 Apache Druid 案例实战 Scala Kafka 订单统计
大数据-156 Apache Druid 案例实战 Scala Kafka 订单统计
40 3
|
1月前
|
SQL 消息中间件 分布式计算
大数据-115 - Flink DataStream Transformation 多个函数方法 FlatMap Window Aggregations Reduce
大数据-115 - Flink DataStream Transformation 多个函数方法 FlatMap Window Aggregations Reduce
36 0
|
1月前
|
SQL 分布式计算 Java
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
34 0
|
1月前
|
缓存 分布式计算 大数据
大数据-90 Spark 集群 RDD 编程-高阶 RDD容错机制、RDD的分区、自定义分区器(Scala编写)、RDD创建方式(一)
大数据-90 Spark 集群 RDD 编程-高阶 RDD容错机制、RDD的分区、自定义分区器(Scala编写)、RDD创建方式(一)
45 0
|
SQL JSON 前端开发
Scala的面向对象与函数编程
Scala的面向对象与函数编程
Scala的面向对象与函数编程