Scala=2.13.4

Martin Odersky
scala最适合用在算法描述领域,java适合用在指令编程领域。
学习Scala从了解编程范式开始

  • 命令式编程(命令式编程关心解决问题的步骤
    • 这就是命令式编程——你要做什么事情,你得把达到目的的步骤详细的描述出来,然后交给机器去运行
    • 这也正是命令式编程的理论模型——图灵机的特点
    • 面向对象编程
  • 函数式编程(函数式编程关心数据的映射
    • 函数式里面的函数有三个重要的特征,而这三个特征就是函数的全部:
    • 函数有一个参数和一个返回值
    • 无论什么情况下同一个函数对确定的参数始终有同样的的返回值
    • 函数的参数和返回值可以是函数
  • 逻辑式编程

为什么Spark会选择Scala?

  • API能做得优雅; 这是框架设计师第一个要考虑的问题,框架的用户是应用开发程序员,API是否优雅直接影响用户体验。
  • 能融合到Hadoop生态圈,要用JVM语言; Hadoop现在是大数据事实标准,Spark并不是要取代Hadoop,而是要完善Hadoop生态。JVM语言大部分可能会想到Java,但Java做出来的API太丑,或者想实现一个优雅的API太费劲。
  • 速度要快; Scala是静态编译的,所以和JRuby,Groovy比起来速度会快很多,非常接近Java。
  • scala为spark做了很多优化工作

语言基础

scala独有的两招:

  • 函数式编程(函数是scala语言中的一等公民,函数式编程的一个重要理念就是要尽量使代码由无状态的函数构成,而不是给计算机发出指令)
  • 简单的并发编程
  • 缺点:Scala (以及任何具有广泛可变性的语言)的代价是,编译器在优化代码方面没有足够的灵活性。Java的提供解决方案是基于运行时来优化代码。
// 在 Scala 中,是没有 static 这个东西的,但是它也为我们提供了单例模式的实现方法,那就是使用关键字 object
object HelloWorld {
  def main(args: Array[String]): Unit = {
  
    println("hello world")

    val myVal : String = "Foo";
    var myVal1 = "Foo";

	// https://docs.scala-lang.org/zh-cn/overviews/collections/arrays.html
	// Scala数组Array[Int]可看作Java的Int[]
	// Array[String]可看作Java的String[]
	// Scala数组是一种泛型。即可以定义一个Array[T],T可以是一种类型参数或抽象类型
	val a1 = Array(1, 2, 3)
	val a2 = a1 map (_ * 3)
	val a3 = Array("Hi", "I", "heard", "about", "Spark")
	
  }
}

Scala函数

// 方法一
def 方法名(参数: 参数类型): 返回值类型 = {
  code block
}

// 方法二
// 不写明返回值的类型,程序会自行判断
def 方法名(参数: 参数类型) = {
  code block
}

// 方法三
def 方法名(参数: 参数类型): 返回值类型 = x + y

// 方法四
val 方法名 = (参数: 参数类型) => func_code
val addInt = (x: Int,y: Int) => x + y
// 方法四引申高级用法,将函数作为参数
val hello = (name: String) => println(s"hello $name")


函数与方法

容器

scala和java容器类型转换
https://docs.scala-lang.org/zh-cn/overviews/collections/conversions-between-java-and-scala-collections.html

Scala的容器库特别强调不可变性,因此提供了大量的新方法将一个容器变换成一个新的容器。
例如,你可能想要像访问Scala容器一样访问某个Java容器,或者你可能想将一个Scala容器像Java容器一样传递给某个Java方法。

import collection.JavaConverters._  

Scala中的下划线

https://blog.csdn.net/i6448038/article/details/50017427

object Sample {
  def main (args: Array[String]) {
  	// (最典型,最常用)这里的下划线代表了集合中的“某(this)”一个元素。这个用法很常见,在foreach等语句中也可以使用
    val newArry= (1 to 10).map(_*2)
    println(newArry)
    
    // 元组Tuple
    val value=(1,2)
    print(value._1)
    
  }
}

Scala类相关

object(没有静态方法和静态字段)

class

case class

样例类是Scala 用于对象模式匹配,并且它不需要大量的样板代码。

样例类是带case 修饰符的类。通过这个修饰符,Scala 编译器对我们的类添加了一些语法上的便利。

case class  C(name:String,age:Int)  // 样例类: name,age 都会被视为字段
​
val c = C("zhang san",20)           // 不需要 new
println("name:" + c.name + " ;age: " + c.age) // name,age 都会被视为字段
println(c.toString)                           // 自动实现了 toString
println(c.hashCode)                           // 自动实现了 hashCode
​
val c2 = c.copy(name="li si")
println(c2.toString)
println(c.equals(c2))                          // 自动实现了 equals
  • Scala 编译器会为样例类添加一个和类同名的工厂方法。这意味着可以使用 C(…) 来构造对象,而不是使用 new C(…) 来构造对象。这样使得代码中不再到处是new 关键字。
  • Scala 编译器会为样例类参数列表中的参数都隐式获取一个val 前缀,因此它们都会被当作字段处理
  • Scala 编译器会帮我们以“自然”的方式实现toString,hashCode,equals 方法。这些方法会分别打印、哈希、比较包含类及所有入参的整棵树。
  • 因为Scala 的 == 总是代理给equals 方法,因此样例类总是以结构化的方式作比较。
  • Scala 编译器还会添加一个copy 方法用于制作修改过的拷贝。这个方法支持带名字的参数,以及缺省参数:可以通过带名字的参数给出希望做的修改;然后对于任何未给出的参数,都会使用旧对象中的原值。

trait 特点 特性

(在Scala中可以通过特征(trait)实现多重继承)
类与单例对象

函数式编程范式

在这里插入图片描述

map
filtermap
flatmap

foreach
reduce
sum

foreach只是用在不需要对集合执行映射操作,但需要遍历集合时才用到。总而言之,foreach用于遍历集合,而map用于映射(转换)集合到另一个集合

DataStream.flatmap(_.split(" ")).map((_, 1)).keyBy(0).sum(1)

创建匿名函数
=>右边是函数体,左边表示函数的参数类型

data.filter(_.nonEmpty)
data.filter(x => x!=null)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值