大数据中日志分析——2、scala常用操作
大数据日志分析相关文章
在master结点搭建code-server
- 软件安装,搭建后访问
masterip:2053 - scala环境部署与hello world尝试
相关学习技能
- scala的简单程序编写
- scala的常用集合操作
- scala的常用高阶函数操作
- scala的面向对象
- scala的模式匹配与正则表达式
常用操作
BASH
1 | # 编译scala文件,会生成class文件 |
scala基本类型
scala基本类型与java相同,但类型名称大写
- Byte
- Short
- Int
- Long
- Char
- Float
- Double
- Boolean
val和var的区别: val定义了值后无法改变(看成final类型),var定义了值可以改变
且每行无需输入分号;
SCALA
1 | // 变量定义:val 变量名: 变量类型 = 值 |
程序控制
条件判断
SCALA1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 一般if操作
// scala是可以直接比较字符串的
if ("test1" == "test2") {
println("1")
} else {
println("12")
}
// 用if语法定义变量,相当于后边是一个函数,会直接输出一个值赋值给前边
// 效果类似于
// var result = ""
// if ("test1" == "test2") {
// result = "right"
// } else {
// result = "wrong"
// }
val result = if ("a" == "b") "right" else "wrong"
println(result)循环操作
SCALA1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35// while循环
var x = 0
while (x < 10) {
x +=x
}
// for循环
// 创建数组
val strArr= Array("a", "b", "c")
// 获取数组每个元素
for (str <- strArr) {
// 格式化输出,直接跟在字符串后边进行format格式化即可
println("arr: %s".format(str))
}
// 获取数组每个元素下标,然后通过下标获取数组元素
for (i <- 0 to strArr.length - 1) {
println("arr:%s".format(strArr(i)))
}
// 生成0到5的集合(即序列)
val nubmerArr = 0 to 5
// 生成0到4的集合(即序列),不包括5
val numberArr = 0 until 5
// 在for循环中生成序列,然后获取符合某条件的数值并对其操作
// yield关键字会把当前元素操作结果记下来,保存在集合中,循环结束后将返回该集合
// 注意,for循环是可以返回结果的
val result = for (number <- 0 to 5 if number % 2 == 0) yield number * 2
println(result)
// 双重for循环,分号前循环一次,分号后循环一轮
// s可以替换字符串中的变量,变量直接用 $变量名 进行表示
for (i <- "abc"; j <- "xyz") println(s"$i + $j")
Array和List常用操作
数组
SCALA1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19// 使用new创建数组,有5个String元素,默认为Null
// Int默认为0
val arr = new Array[String](5)
arr(0) = "asdf"// 获取下标然后赋值
println(arr)// 直接输出会输出哈希值
// 使用apply方式定义数组,可以不写类型。不加new关键字就是用apply方式来申请对象
val arr = Array[Int](20, 30)
val arr = Array(20, 30)
// Array遍历,直接获取每个元素
for (number <- arr) {
println(number)
}
// 先获取下标,在获取数组数据,获取数组长度用arr.length
for (index <- 0 until arr.length) {
println(arr(index))
}List
SCALA1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36// 创建一个List,输出是顺序输出
val list = List(1, 2, 3)
// 通过Nil和::追加符创建List
// Nil是一个空的List(),所以这里的操作流程是从右向左,先创建一个空的List(),然后再依次添加3,2,1这3个元素
val list = 1 :: 2 :: 3 :: Nil
// 元素添加到尾部,使用:+,然后后边添加元素 。
val result = list :+ 5
// 元素添加到头部,使用::,然后头部添加元素
val result = 5 :: list
// 将List转为字符串,通过_下划线进行连接
val result = list.mkString("_")
// 获取List第一个元素,通过head属性
val result = list.head
// 获取List最后一个元素,通过last属性
val result = list.last
// 获取List前3个元素,通过take属性,生成新的List
val result = list.take(3)
// List的遍历
// 获取每一个元素来遍历
for (t <- list) {
println(t)
}
// 获取每一个索引来遍历
for (index <- 0 until list.length) {
println(list(index))
}
// 也可以用list自带的foreach方法
list.foreach(t => println(t))
Set, Map和Tuple操作
SCALA
1 | // scala默认导入了下边的三个包 |
Set
SCALA1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 创建一个Set,下边的情况不会有重复元素,输出乱序
val set = Set(1, 2, 4, 4)
// 新添加元素,需要用新的变量接收
val newSet = set + 5
// 创建可变的Set,需导入scala.collection.mutable._
val set = Set(1, 2, 4)
set.add(3)
// 遍历方式,使用set的foreach
set.foreach(x -> println(x))
// 使用for循环
for (x <- set) {
println(x)
}Map
SCALA1
2
3
4
5
6
7
8
9
10// 创建一个map。默认是的包是不可变的
val map = Map("age" -> 14, "isBoy" -> true, "name" -> "kim")
// 定义可变的Map,需导入scala.collection.mutable._
// map只能加入相同类型的值,这里只是Int类型的值,加入String类型的值就会报错
val map = Map("age" -> 1, "isBoy" -> 2, "name" -> 3)
map.put("height" -> 130)
// Map遍历,会获取到Map中的每一个元组,获取每个元祖的键值通过x._1, x_2即可
map.foreach(x => println(x))
map.foreach(x => println(x._1))Map是scala中的一个类,map是scala中的一个高阶方法Tuple
SCALA1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// 定义一个元组Tuple,Tuple值可以包含多种类型
val tuple = ("a", 1, 1.2, true)
// 二元组的特殊定义方式,所以可以看成Map中每个元素都是一个Tuple
val tuple = "test" -> 1
// 访问Tuple中第一个元素,下标从1开始
val result = tuple._1
// 模式匹配获取元素内容,括号内是变量,然后从后边的变量中获取值
// 括号内变量个数需要和元组个数相同
val (a, b) = tuple
// tuple遍历直接使用tuple._x即可或者通过for循环获取每个元素下标再遍历
for (index <- 0 until tuple.productArity) {
println(tuple.productElement(index))
}
// 或者使用迭代器遍历tuple的每一个元素
for (item <- tuple.productIterator) {
println(item)
}
函数和常见高阶函数
SCALA
1 | // 函数格式:def 函数名(参数1: 类型1, 参数2: 类型2): 返回值类型 = {函数体},函数返回值可以不写return |
类和对象
主构造器(用于定义类)
SCALA1
2
3
4
5
6
7
8
9
10
11
12
13
14// 定义一个类, 有三个成员变量,city有默认值
// 函数的函数体有等号,类不需要等号
// 然后覆写toString方法
class Person(var name: String, var age: Int, var city: String = "Beijing") {
// 一行函数体可以不加大括号
override def toString() = "name: %s, age: %d, city: %s".format(name, age, city)
// 也可以如下,更简洁
// override def toString() = s"name: $name, age: $age, city: $city"
}
// 有默认值的参数可以不传值,没有默认值的参数需要传值
val p = new Person("Easul", 18)
// 修改参数之后,对象的参数就可以被修改
p.age = 21单例对象
scala没有static,所以通过单例对象来实现静态,从而避免总是创建对象。也可以当作普通的单例来使用SCALA1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// object关键字用于创建单例对象
object Person {
private var personId = 0
def outputId(): Int = {
personId += 1
personId
}
// 使用main函数作为整个项目入口,返回Unit与void相同,表示默认不返回任何值
def main(args: Array[String]): Unit = {
println("PersonId: %s".format(outputId()))
// 也可以通过类名调用
// println("PersonId: %s".format(Person.outputId()))
}
}伴生对象和伴生类
SCALA1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26// 这里有一个Person类和Person单例对象
// Person类是Person单例对象的伴生类
// Person单例对象是Person类的伴生对象
// 伴生类和伴生对象之间的属性可以互相访问
class Person(var name: String, var age: Int, var city: String = "Beijing") {
// 伴生类可以访问伴生对象的私有属性
def outputIdFromClass() = println("personIdFromClass: " + Person.personId)
}
// object关键字用于创建单例对象
object Person {
private var personId = 0
def outputId(): Int = {
personId += 1
personId
}
// 使用main函数作为整个项目入口
def main(args: Array[String]): Unit = {
println("PersonId: %s".format(Person.outputId()))
// 伴生对象中访问半生类需要先创建对象
val p = new Person("Easul", 18)
p.outputIdFromClass()
}
}apply方法
创建对象不使用new关键字,默认调用了该类伴生对象的apply方法SCALA1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 伴生类需要默认传参数
class Person(var name: String, var age: Int, var city: String = "Beijing") {
override def toString() = s"name: $name, age: $age, city: $city"
}
// 伴生对象不需要传参数
object Person {
// 创建的对象需要什么参数,apply就传什么参数,可以不加var关键字
// apply方法是默认实现的,自己可以不写
def apply(name: String, age: Int, city: String = "Beijing") = new Person(name, age, city)
def main(args: Array[String]): Unit = {
// 使用apply方法,只要参数有默认值,也可以不传值
val p = Person("Easul", 18)
println(p)
}
}
模式匹配与正则表达式
模式匹配
SCALA1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57// 常量匹配
// 参数类型为Any表示接收任何类型的参数。
// match表示对x这个值的switch判断
def constPattern(x: Any): String = x match{
case 0 => "zero"
case 1 => "one"
// 下划线表示其他所有情况
case _ => "other situation"
}
// 变量匹配
def variablePattern(x: Any): String = x match {
case 1 => "one"
// 变量匹配的其他情况可以用一个变量接收,然后后边可以对这个变量进行操作
case a if a.endsWith("a") => "two"
case b => s"other situation: $b"
}
// 类型匹配,用于判断变量的类型
def typePattern(x: Any): String = x match {
case a: Int => "Int"
case b: Double => "Double"
case c: String => "String"
case d: Boolean => "Boolean"
case _ => "other type"
}
// 构造器匹配,用于匹配类和对象
// 构造器匹配,类需要定义为case class
case class Person(var name: String, var age: Int, var city: String = "Beijing") {
override def toString() = s"name: $name, age: $age, city: $city"
}
def constructorPattern(x: Any): String = x match {
// Person()括号内的参数只是用于占位置
case Person(name, age, city) => s"name: $name, age: $age, city: $city"
case _ => "other constructor"
}
val p = new Person("Easul", 18)
println(typePattern(p))
println(typePattern('3'))
// 序列匹配
def pattern(x: Any): String = x match {
// List中要有三个元素,其他情况不匹配
case List(one ,two, three) => s"List => one: $one, two: $two, three: $three"
// Array中至少有两个元素,这里只匹配第二个元素,_*表示可以匹配0个或多个参数。只有一个元素则不匹配
case Array(_, two, _*) => s"Array => two: $two"
case _ => "other"
}
// 元组匹配
def tuplePattern(x: Any): String = x match {
case () => "empty tuple"
case (_, two, three) => s"two: $two, thre: $three"
case _ => "other"
}
tuplePattern(1 -> 2)正则表达式
SCALA1
2
3
4
5
6
7
8// 通过正则字符串后边加.r创建正则,加括号可以获取到符合的数据
val regex_1 = "(\\d+)\\s+(\\w+)!".r
// 通过创建对象来创建正则,需要导入scala.util.matching.Regex
val regex = new Regex("(\\d+)\\s+(\\w+)!")
val text = "123 abc!"
// 将text的数据通过regex正则将需要的数据赋值给d和w
val regex(d, w) = text
println(s"$d + $w")
常用特殊符号的含义
YAML
1 | "->": 用于构造二元组,如"val x = 1 -> 2" |
相关示例
SCALA
1 | // 使用->创建一个二元组 |
- 本文标题:大数据中日志分析——2、scala常用操作
- 创建时间:2022-02-28 13:24:26
- 本文链接:https://blog.212490197.xyz/article/program/bigdata/scala-simple-operation/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
评论