主要用来处理数据,不处理web,没有类似spring的框架
1. Scala简介
我们基于的scala版本 2.12.10
scala是运行在 JVM 上的多范式(规范)编程语言,同时支持面向对象和面向函数编程。(真实数据与操作过程解耦)
早期scala刚出现的时候,并没有怎么引起重视,随着Spark和Kafka这样基于scala的大数据框架的兴起,scala逐步进入大数据开发者的眼帘。scala的主要优势是它的表达性。
官网地址 http://www.scala-lang.org
2. 为什么要使用scala
- 表达能力强
- 开发大数据应用程序(Spark程序、Flink程序)
- 兼容Java,可以访问的Java类库
- 支持「并发」
3. 安装IDEA的Scala插件
pom文件添加依赖:
XML
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.12.8</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.12</artifactId>
<version>2.4.7</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_2.12</artifactId>
<version>2.4.7</version>
</dependency>
IDEA默认是不支持scala程序开发,所以需要来安装Scala插件来支持Scala语言。
-
添加Scala插件后,重启IDEA
-
需要在project structure --> global libiray 添加scala 2.11.10 依赖(IDE2024没有添加,也可以正常使用)
-
创建.scala文件

入门案例:
Scala
//object: 静态类,这个类里面的所有方法都是静态的,
object demo1 {
def main(args: Array[String]): Unit = {
print("scala测试")
}
}
// 实例的概念
class demo1{
def met1(): Unit = { // Unit代表没有返回的值
}
}
运行结果:

4. Scala中声明变量
语法格式:
Scala
val/var 变量名称:变量类型 = 初始值
其中
`val`定义的是**不可重新赋值**的变量(值不可修改) :常量
`var`定义的是**可重新赋值**的变量(值可以修改):变量
Scala
val param1:String = "测试scala"
var param2:Int = 100
println(param1)
println(param2)
5. 方法和函数
5.1 方法
语法
Scala
def methodName (参数名:参数类型, 参数名:参数类型) : [return type] = {
// 方法体
}
说明
-
参数列表的参数类型不能省略
-
返回值类型可以省略,由scala编译器自动推断
-
返回值可以不写return,默认就是{}块表达式的值
方法的参数
默认参数:在定义方法时可以给参数定义一个默认值。
带名参数:在调用方法时,可以指定参数的名称来进行调用。
Scala
def method1(v1:Int, v2: Int)= {
v1 + v2
}
def method2(v1:Int = 12, v2:Int = 13) = { // 可以指定默认值
v1 + v1 + v2
}
def main(args: Array[String]): Unit = {
println(method1(3,5))
println(method2(v2=12, v1=10)) // 可以带变量名赋值
}
运行结果:

注意:如果定义递归方法,不能省略返回值类型
5.2 函数
Scala支持函数式编程,将来编写Spark/Flink程序中,会大量使用到函数
语法
Scala
val 函数变量名 = (参数名:参数类型) => 函数体
注意
-
函数是一个变量,长的与方法相似,但不同于方法
-
类似于方法,函数也有输入参数和返回值
-
函数定义不需要使用def定义,而是用val定义
-
无需指定返回值类型
Scala
val function1 = (v5:Int) =>{
println(v5)
}
def main(args: Array[String]): Unit = {
function1(8)
}
5.3 case class
-
创建 case class 和它的伴生 object
-
实现了 apply 方法让你不需要通过 new 来创建类实例
-
添加天然的 hashCode、equals 和 toString 方法。由于 == 在 Scala 中总是代表 equals,所以 case class 实例总是可比较的
-
默认为主构造函数参数列表的所有参数前加 val
Scala
case class demo2(v1: Int)
6. 高阶函数
使用函数值作为参数,或者返回值为函数值的"函数"和"方法",均称之为"高阶函数"
意义:将实际数据,与执行动作进行解耦
7. 函数式编程
理念:数据与动作的解耦
原理:类的实例当做参数传入
我们将来使用Spark/Flink的大量业务代码都会使用到函数式编程
"函数式编程"是一种"编程范式"(programming paradigm)
****函数式编程****是从编程方式(范式)的角度来谈的,可以这样理解:函数式编程把函数当做一等公民,**充分利用函数**、 支持的函数的多种使用方式,主要思想是把运算过程尽量写成一系列嵌套的函数调用
集合的分类\](https://zhuanlan.zhihu.com/p/25512292) **\*\*foreach\*\*** (学会认识方法,要怎么传递参数) 方法描述:接收一个函数对象,函数的输入参数为集合的元素 需要传入一个函数类型A 返回是一个空 ```Scala foreach(f: (A) => Unit): Unit ``` 示例 ```Scala // 函数的意义:数据跟动作做解耦 def testForeach(): Unit = { val list = List(1,2,3,4,5) val f = (x: Int) => print(x) list.foreach(f) // 简便写法 list.foreach((x:Int) => print(x)) list.foreach(x => print(x)) list.foreach(println(_)) // 下划线代表每一个元素 list.foreach(println) } ``` **\*\*映射 - map\*\*** 集合的映射操作是将来在编写Spark/Flink用得最多的操作,是我们必须要掌握的掌握。 方法描述:传入一个函数对象,该函数接收一个类型A,返回值为类型B ```Scala def map[B](f: (A) ⇒ B): TraversableOnce[B] ``` 示例 ```Scala def mapTest(): Unit = { val list = List(1,2,3,4,5) val list2: List[String] = list.map((x:Int) => x.toString) val list3: List[String] = list.map(x => x.toString) val list4: List[String] = list.map(_.toString) val list5: List[Int] = list.map(_ + 1) print(list5) } def main(args: Array[String]): Unit = { mapTest() } ``` 隐式转换: 通过隐式转换,程序员可以在编写Scala程序时故意漏掉一些信息,让编译器去尝试在编译期间自动推导出这些信息来,这种特性可以极大的减少代码量,忽略那些冗长,过于细节的代码 **\*\*扁平化映射 - flatmap\*\*** 映射扁平化也是将来用得非常多的操作,也是必须要掌握的。 方法描述:\[B\]最终要转换的集合元素类型,传入一个函数对象,函数的参数是集合的元素,函数的返回值是一个集合 ```Scala def flatMap[B](f: (A) ⇒ GenTraversableOnce[B]): TraversableOnce[B] ``` 示例 可以理解为读取一行数据 \~\~\~scala \~\~\~ ### \*\*过滤 - filter\*\* 方法描述:传入一个函数对象,接收一个集合类型的参数,返回布尔类型,满足条件返回true, 不满足返回false \`\`\`scala def filter(p: (A) ⇒ Boolean): TraversableOnce\[A
```
方法实操:
~~~scala
~~~
**排序 - sort**
在scala集合中,可以使用以下几种方式来进行排序
sorted默认排序
演示
~~~~scala
~~~~
**sortWith自定义排序**
自定义排序,根据一个函数来进行自定义排序
方法描述
~~~scala
def sortWith(lt: (A, A) ⇒ Boolean): List[A]
~~~
方法实操
~~~scala
~~~
**tip:元组**
就是为了操作方便,而给我们提供的一个类型,可以存放不同数据类型在一个元组中。可以理解为可以存放不同类型数据的一个list
**分组 - groupBy**
我们如果要将数据按照分组来进行统计分析,就需要使用到分组方法,groupBy表示按照函数将列表分成不同的组
方法描述
Scala
def groupBy[K](f: (A) ⇒ K): Map[K, List[A]]
方法实操
Scala
def groupTest(): Unit = {
val list = List(("jack", 2000), ("tom", 2500), ("tom", 5600))
val res = list.groupBy(_._1).mapValues(_.map(_._2)).map(x => x._1 + x._2.sum)
print(res)
}
def main(args: Array[String]): Unit = {
groupTest()
}

**聚合 - reduce**
reduce表示将列表,传入一个函数进行聚合计算
方法描述
~~~scala
def reduce[A1 >: A](op: (A1, A1) ⇒ A1): A1
~~~
方法说明
| reduce方法 | API | 说明 |
| ---------- | ----------------- | ------------------------------------------------------------ |
| 泛型 | [A1 >: A] | (下界)A1必须是集合元素类型的子类 |
| 参数 | op: (A1, A1) ⇒ A1 | 传入函数对象,用来不断进行聚合操作<br />第一个A1类型参数为:当前聚合后的变量<br />第二个A1类型参数为:当前要进行聚合的元素 |
| 返回值 | A1 | 列表最终聚合为一个元素 |
scala _ 下划线用法
-
作为"通配符",类似Java中的*
-
指代一个集合中的每个元素
-
在元组中,可以用方法1, _2, _3访问组员
-
使用模式匹配可以用来获取元组的组员
-
下划线_代表的是某一类型的默认值